ocaml - 获取 OCaml 中 float 的精度

标签 ocaml

我想为我的应用程序获取十进制数的精度, 我尝试了几种方法,但我无法得到我想要的。

在开始时,我尝试将 float 转换为字符串,并对它进行简单拆分并将其存储在一个整数列表中,然后获取列表的长度

let a = 12.12345678910111213141516;;
let stringA = string_of_float a;;

let list_of_ints stringA = List.map int_of_string (Str.split (Str.regexp "\.") stringA);;
let stringList = list_of_ints stringA;;
let thedecimal = string_of_int (List.nth stringList 1);;

S.length thedecimal;;

问题是每当我的 float 的特征侧有超过 10 个数字时它就不起作用,它总是返回 10

val a : float = 12.1234567891011125
val stringA : string = "12.1234567891"
val list_of_ints : string -> int list = <fun>
val stringList : int list = [12; 1234567891]
val thedecimal : string = "1234567891"
- : int = 10

我的第二种方法是尝试在 float 和 它的特点,所以我得到了尾数,然后把它放在一个 list 上,然后 得到它的长度减去 2(0 和 .)

let b = int_of_float a;;
let c = a -. (float_of_int b);;
S.length (string_of_float c)-2;; 

它返回 12,这很奇怪,因为我期待的是 23,

val b : int = 12
val c : float = 0.123456789101112463
- : int = 12

我是 Ocaml 的新手。如果有人对如何获得精度有任何解决方案,我需要您的帮助,谢谢。

最佳答案

显然,string_of_float 决定将显示的有效数字位数限制为十二位(我必须仔细研究才能确定)。

这实际上是一件好事,因为 double 可以表示为一个相当大的数字。

# let f = 0.123456789012345678901234567890;;   
val f : float = 0.123456789012345677
# let s = string_of_float f;;
val s : string = "0.123456789012"
# let s' = Printf.sprintf "%.10f" f;;
val s' : string = "0.1234567890"
# let s'' = Printf.sprintf "%.30f" f;;
val s'' : string = "0.123456789012345677369886232100"
# let s''' = Printf.sprintf "%.60f" f;;
val s''' : string =
  "0.123456789012345677369886232099815970286726951599121093750000"
(* longer than this one just add zeroes *)

现在,您要求的是一个数字的实际精度。根据 Wikipedia :

  • Sign bit: 1 bit
  • Exponent: 11 bits
  • Significand precision: 53 bits (52 explicitly stored)

此外...

The format is written with the significand having an implicit integer bit of value 1 (except for special data, see the exponent encoding below). With the 52 bits of the fraction significand appearing in the memory format, the total precision is therefore 53 bits (approximately 16 decimal digits, 53 log10(2) ≈ 15.955).

Between 252=4,503,599,627,370,496 and 253=9,007,199,254,740,992 the representable numbers are exactly the integers. For the next range, from 253 to 254, everything is multiplied by 2, so the representable numbers are the even ones, etc. Conversely, for the previous range from 251 to 252, the spacing is 0.5, etc.

The spacing as a fraction of the numbers in the range from 2n to 2n+1 is 2n−52. The maximum relative rounding error when rounding a number to the nearest representable one (the machine epsilon) is therefore 2−53.

所以你知道了,你的精度大约是 2^-53 关于你的 float 。这为任何 float 提供了大约 15 或 16 位十进制数的精度

附带说明一下,如果您在 float 上使用正则表达式,则需要冷静下来,花一分钟时间想想小猫。

关于ocaml - 获取 OCaml 中 float 的精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41119026/

相关文章:

types - Coq 到 OCaml 的代数类型提取

syntax - OCaml 显式类型签名

algorithm - 重新排序递归函数中的匹配子句

ocaml - 如何在 OCaml 中发送电子邮件,设置 `Content-Type: Multipart/Alternative`

ocaml - 是否有使用OCaml开发的Window Manager?

ocaml - 如何在交互式Ocaml中获取类型信息?

graphics - 如何编译ocaml图形窗口cygwin

ocaml - 如何在 OCaml 中打印调用函数的文件位置?

将两个排序列表合并为一个排序列表的函数的 OCaml 样式

ocaml - `brew install infer` 更新推断时出错