Reputation: 779
floor
in Haskell is defined only for the RealFrac
typeclass. I don't really know much about this typeclass and the rest of my code only uses floating point numbers.
I can't find any function for casting a Float
to an Int
. If there were then floor
would be equivalent to fromIntegral (fromFloating x)
and fract
would be defined as
fract x = x - floor x
However, as I said, I haven't found any function that does anything like what I want fromFloating
to do. So this is the only way I could think of for implementing fract
:
fract x
| x < 0 = 1 - fract (abs x)
| x < 1 = x
| otherwise = fract (x - 1)
and then of course floor x
would be x - fract x
. The algorithm above, however, is O(n) and it's going to drastically slow things down, so I'm hoping there's a way to do this that is constant time.
Upvotes: 1
Views: 683
Reputation: 23548
As the comments say, floor
is already implemented for floating point numbers, and frac
is straightforward; this code compiles:
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)
and produces:
$ runhaskell /tmp/a.hs
aDouble is
-5.675
frac(aDouble) is
0.3250000000000002
aFloat is
10.675
frac(aFloat) is
0.6750002
Upvotes: 1