【问题标题】:Engineering notation with Haskell使用 Haskell 的工程符号
【发布时间】:2015-04-28 16:17:24
【问题描述】:

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

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


我所说的工程符号是指指数是3的倍数的指数符号。

【问题讨论】:

    标签: haskell floating-point formatting floating-point-precision scientific-notation


    【解决方案1】:

    经过一番研究,我设法得到了我想要的。 只需几步即可获得工程格式的功能:

    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 对大范围和大量值进行了一些测试。尽管值的差异非常小(在计算过程中由于精度而四舍五入?),但转换似乎运行良好。

    但是,应该进行其他验证。

    如果您发现这些功能有错误或改进,请分享。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 这似乎不符合规范,“其指数是 3 的倍数”。具体来说,expt 0 10 给出了"1e2",而 2 不是 3 的倍数。
      • @DanielWagner 这很奇怪;在图书馆里,它说它是工程符号。这可能是一个错误。
      【解决方案3】:

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

      的独立函数
      showEngineer :: Double -> String
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-19
        • 2015-11-05
        • 2017-10-22
        • 1970-01-01
        • 2010-11-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多