Haskell中获取Double机器精度:是否有内置方法?自定义实现正确吗?
Haskell中获取Double机器精度的方法
内置方法
Haskell标准库提供了直接获取Double机器精度(即机器epsilon,定义为最小的正数ε,使得1.0 + ε ≠ 1.0)的方式:
- 使用
Data.Double模块的doubleEpsilon常量,它直接对应Double的机器epsilon值(2^-52)。 - 借助
Numeric.Floating类型类的machineEpsilon方法,Double实例的该方法会返回相同的机器epsilon。 - 也可以通过基础函数计算:对于任意Double值
d,机器epsilon可通过fromIntegral (floatRadix d) ** (1 - floatDigits d)得到——Double的floatRadix为2,floatDigits为53,代入后结果同样是2^-52。
自定义实现的正确性
你给出的代码是正确的,能够准确获取Double的机器精度:
machinePrecision :: Double machinePrecision = until isSmall half 1.0 where isSmall :: Double -> Bool isSmall x = 1.0 + x / 2.0 == 1.0 half :: Double -> Double half x = x / 2.0
这段代码的逻辑是从1.0开始不断将值减半,直到1.0 + x/2.0与1.0在浮点数运算中无法区分(即精度丢失),此时返回的x就是机器epsilon。对于Double类型,最终结果正好是2^-52,完全符合机器epsilon的定义。
内容的提问来源于stack exchange,提问作者Stéphane Laurent
相关产品推荐
相关产品推荐

