Haskell的工程符号



是否有现有的Haskell函数提供工程符号格式(字符串)?

如果没有,我读到printf可以通过向PrintfArg添加一个实例来扩展。你认为这是一个好的解决方案吗?


通过工程符号,我指的是指数是3的倍数的指数符号

经过一番研究,我终于得到了我想要的东西。通过几个步骤获得工程格式的功能:

1.将指数与尾数分离

有必要把指数和尾数分开。函数decodeFloat(由base提供)解码浮点数,并返回尾数和指数的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对大范围和大量值进行了一些测试。尽管的值差很小,但转换似乎运行良好(由于精度的原因,在计算过程中四舍五入?)。

但是,应进行另一次验证。

如果您发现这些功能存在错误或改进,请与我们分享。

Data.Text.Format中,有一个expt函数可以帮助以这种方式格式化数字,尽管它位于一个非常模糊的库中,恐怕您必须从Text转换为String

这似乎是唯一可用的,但你总是可以自己做一个。

我不知道标准函数。向printf添加一些内容是一种方法,但使用起来会有点烦人(因为您需要为工程符号格式的数字添加一个新类型,并在将数字转换为该类型后再将其传递)。简单地用这样的类型编写一个独立的函数

showEngineer :: Double -> String

从长远来看,这可能是一个更简单、更可读的解决方案。

相关内容

  • 没有找到相关文章

最新更新