2017-08-22 75 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 
相關問題