2017-08-22 27 views
1

floor在Haskell中仅为RealFrac类型类定义。我不太了解这个类型类,而我的其他代码只使用浮点数。在Haskell中实现浮点数的最佳方式?

我找不到任何功能将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 xx - fract x。然而,上面的算法是O(n),它会大幅度减慢速度,所以我希望有一种方法可以做到这一点。

+0

'floor'函数具有以下类型'地板::(RealFrac一个,积分B)=>一 - > B',所以可以将其实例化为一个Float并返回一个Int(https://www.haskell.org/hoogle/?hoogle=floor) – Euge

+0

值得注意的是,Float和Double都是RealFrac的实例,因此您使用的关注点他们而不是使用RealFrac是错位的。 – amalloy

+0

为什么不'fract = snd。 properFraction'? ('fract = \ x - > x - fromIntegral(floor x)'具有正确的类型,几乎可以做你想做的,但对于负数不起作用)。这里完全没有必要将'Float''投射'到'Int'(无论'cast'实际上对你意味着什么)。 – user2407038

回答

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 
相关问题