在Haskell中为浮点数实现floor和fract的最佳方法是什么?

时间:2017-08-22 00:42:23

标签: haskell optimization floating-point

Haskell中的

floor仅针对RealFrac类型类定义。我不太了解这个类型类,我的其余代码只使用浮点数。

我无法找到将Float投射到Int的任何功能。如果有,那么floor将等同于fromIntegral (fromFloating x)fract将被定义为

fract x = x - floor x

然而,正如我所说,我还没有找到任何能够做我想做fromFloating之类的事情的功能。所以这是我能够考虑实施fract的唯一方法:

fract x 
    | x < 0 = 1 - fract (abs x)
    | x < 1 = x
    | otherwise = fract (x - 1)

然后当然floor x将是x - fract x。然而,上面的算法是O(n),它会大大减慢速度,所以我希望有一种方法可以做到这一点,这是一个恒定的时间。

1 个答案:

答案 0 :(得分:1)

正如评论所说,floor已经实现了浮点数,frac很简单;这段代码编译:

aDouble :: Double
aDouble = -5.675

aFloat :: Float
aFloat = 10.675

frac :: RealFrac a => a -> a
frac x = x - fromIntegral (floor x :: Integer)

main :: IO ()
main = do
  putStrLn "aDouble is"
  print aDouble
  putStrLn "frac(aDouble) is"
  print (frac aDouble)
  putStrLn "aFloat is"
  print aFloat
  putStrLn "frac(aFloat) is"
  print (frac aFloat)

并产生:

$ runhaskell /tmp/a.hs
aDouble is
-5.675
frac(aDouble) is
0.3250000000000002
aFloat is
10.675
frac(aFloat) is
0.6750002