2017-08-22 9 views
1

floorは、RealFrac typeclassについてのみ定義されています。私はこのtypeclassについてよく知らないし、残りのコードは浮動小数点数しか使わない。ハスケルの浮動小数点数のためにfloorとfractを実装する最良の方法は? Haskellの

FloatIntにキャストする機能が見つかりません。あった場合、floorfromIntegral (fromFloating x)fractに相当します

fract x = x - floor x 

として定義されるだろう、私が言ったようにしかし、私はfromFloatingが何をしたいかのように何もしないすべての機能を発見していません。

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

、その後、もちろんfloor xx - fract x次のようになります。これは、私がfractを実装するための考えることができる唯一の方法です。しかし、上のアルゴリズムはO(n)であり、物事を大幅に遅くすることになるので、一定の時間でこれを行う方法があることを期待しています。

+0

'floor'機能は以下の型'階::(RealFrac、インテグラルB)=>を持つA - > 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'に 'キャストする 'ことはまったく必要ありません(キャストは実際にあなたに意味します)。 – 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 
関連する問題