Desired behaviour of rounding etc.

Daniel Fischer daniel.is.fischer at web.de
Fri Oct 8 08:08:01 EDT 2010


The methods of the RealFrac class produce garbage when the value lies 
outside the range of the target type, e.g.

Prelude GHC.Float> truncate 1.234e11 :: Int  -- 32-bits
-1154051584

and, in the case of truncate, different garbage when the rewrite rule 
fires:

Prelude GHC.Float> double2Int 1.234e11
-2147483648

I'm currently working on faster implementations of properFraction, 
truncate, round, ceiling and floor for Float and Double, so I'd like to 
know

- does it matter at all what garbage is returned in the above case?
- if it does, what is the desired behaviour (at least for Int, I can't 
cater for all possibilities)?


On a related note, in my benchmarks,

truncFloatGen :: Integral a => Float -> a
truncFloatGen = fromInteger . truncFloatInteger

truncFloatInteger :: Float -> Integer
truncFloatInteger x =
  case decodeFloat x of
    (m,e) | e == 0  -> m
          | e < 0   ->
            let s = -e
            in if m < 0
                  then - ((-m) `shiftR` s)
                  else m `shiftR` s
          | otherwise -> m `shiftL` e

is more than twice as fast as GHC.Float.float2Int, the corresponding for 
Double almost twice as fast as double2Int.

Can anybody confirm that the above is faster than float2Int on other 
machines/architectures?

Cheers,
Daniel


More information about the Libraries mailing list