Proper rounding of floating-point values

Much to my surprise, there does not seem to be a function in base (let alone the Prelude) that rounds floating point numbers correctly in the presence of NaNs and infinities. For example:
round (0/0 :: Double) :: Int 0 round (0/0 :: Double) :: Integer -269653970229347386159395778618353710042696546841345985910145121736599013708251444699062715983611304031680170819807090036488184653221624933739271145959211186566651840137298227914453329401869141179179624428127508653257226023513694322210869665811240855745025766026879447359920868907719574457253034494436336205824 round (1/0 :: Double) :: Int 0 round (1/0 :: Double) :: Integer 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216
This is because the 'round' function must return an instance of Integral, which Double is not. In the presence of NaNs and infinities, this does not fly. In my own code, I ended up just using the FFI to call out to C, which is simple enough: foreign import ccall "round" c_round :: Double -> Double foreign import ccall "roundf" c_roundf :: Float -> Float However, it does disturb me a bit that I cannot find a standard way to do this fairly common operation. (GHC's implementation does seem to avoid many other common pitfalls[0], probably because it does use C's round() under the covers.) [0]: https://www.cockroachlabs.com/blog/rounding-implementations-in-go/ -- \ Troels /\ Henriksen
participants (1)
-
Troels Henriksen