是否存在提供工程符号格式(作为字符串)的现有 Haskell 函数?
如果不是,我读到 printf
可以通过向 PrintfArg
添加一个实例来扩展。您认为这是一个好的解决方案吗?
我所说的工程符号是指指数是3的倍数的指数符号。
经过一番研究,我设法得到了我想要的。只需几步即可获得工程格式的功能:
1.将指数与尾数分离
有必要将尾数中的指数分开。decodeFloat
函数(由 base
提供)解码 float 并返回尾数和指数 2 的幂次 (mant2 * 2 ^ ex2).
<强>2。获取以正确底数表示的尾数和指数
需要10 次方 的转换。这就是这个函数的作用。
decompose :: Double -> (Double,Int)
decompose val = if mant2 > 0
then (mant10,ex10)
else (-mant10,ex10)
where
(mant2,ex2) = decodeFloat val
res = logBase 10 (fromIntegral (abs mant2)::Double) + logBase 10 (2 ** (fromIntegral ex2::Double))
ex10 = floor res
mant10 = 10**(res - (fromIntegral ex10::Double))
3.将指数设置为 3 的倍数
ingen
函数测试指数整数除法的结果,并对尾数和指数进行调整。
ingen :: Double -> (Double,Int)
ingen val
| mod ex 3 == 0 = (mant,ex)
| mod ex 3 == 1 = (mant*10,ex-1)
| mod ex 3 == 2 = (mant*100,ex-2)
where
(mant,ex) = decompose val
这里有一些转换:
Prelude> ingen 10e7
(99.99999999999979,6)
Prelude> ingen 10e-41
(100.0,-42)
Prelude> ingen (-72364e81)
(-72.36399999999853,84)
我使用 quickCheck 对大范围和大量值进行了一些测试。尽管值的差异非常小(由于精度而在计算过程中四舍五入?),但转换似乎运行良好。
但是,应该进行其他验证。
如果您发现这些功能有错误或改进,请分享。
我是一名优秀的程序员,十分优秀!