gpt4 book ai didi

floating-point - OCaml是否具有类似C的round()和trunc()函数?

转载 作者:行者123 更新时间:2023-12-04 13:38:22 26 4
gpt4 key购买 nike

OCaml的标准库包括几个等效于C的浮点函数,例如C的mod_floatfmod(),C的**的幂运算符pow()以及其他函数(例如ceillog等)。

但是它还包括round()trunc()的等效项吗?有truncate/int_of_float,但是它们的类型是float -> int而不是float -> float

最佳答案

它包含modf函数,这是瑞士刀函数,可用于定义truncatefroundf函数:

# let truncatef x = snd (modf x);;
val truncatef : float -> float = <fun>
# truncatef 3.14;;
- : float = 3.
round函数也可以用 modf表示
# let roundf x = snd (modf (x +. copysign 0.5 x));;
val roundf : float -> float = <fun>
# roundf 3.14;;
- : float = 3.
# roundf 3.54;;
- : float = 4.
# roundf (~-.3.54);;
- : float = -4.

但是,可以使用 floor更加简洁(有效)地表示它
# let roundf x = floor (x +. 0.5)

但是,这两个舍入函数都存在一些问题,因为 core的实现注释如下:
(* Outside of the range [round_nearest_lb..round_nearest_ub], all representable doubles
are integers in the mathematical sense, and [round_nearest] should be identity.

However, for odd numbers with the absolute value between 2**52 and 2**53, the formula
[round_nearest x = floor (x + 0.5)] does not hold:

# let naive_round_nearest x = floor (x +. 0.5);;
# let x = 2. ** 52. +. 1.;;
val x : float = 4503599627370497.
# naive_round_nearest x;;
- : float = 4503599627370498.
*)
let round_nearest_lb = -.(2. ** 52.)
let round_nearest_ub = 2. ** 52.

因此,实现舍入的更正确方法是(来自Core库):
let round_nearest t =
if t >= round_nearest_lb && t <= round_nearest_ub then
floor (t +. 0.5)
else
t

但是,即使这个 round_nearest也不是完美无缺的,例如:
# round_nearest 0.49999999999999994;;
- : float = 1.

0.499999999999999940.5的直接前身。 Pascal的 blog包含有关如何解决此问题的建议。以下应该在OCaml中起作用:
let round_nearest t =
if t >= round_nearest_lb && t <= round_nearest_ub then
floor (t +. 0.49999999999999994)
else
t

# round_nearest 0.49999999999999994;;
- : float = 0.
# round_nearest (~-.0.49999999999999994);;
- : float = 0.
# round_nearest (~-.1.49999999999999994);;
- : float = -1.
# round_nearest 0.5;;
- : float = 1.
# round_nearest ~-.0.5;;
- : float = -1.
#

这只是一种舍入策略,四舍五入到最接近的值(直观的一种)。还有其他一些政策,它们都有自己的警告。

关于floating-point - OCaml是否具有类似C的round()和trunc()函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30732709/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com