[Haskell-cafe] Desired behaviour of rounding etc.
marlowsd at gmail.com
Tue Oct 12 05:18:39 EDT 2010
On 09/10/2010 10:07, Daniel Fischer wrote:
> On Saturday 09 October 2010 06:34:32, Lennart Augustsson wrote:
>> That code is incorrect. You can't assume that the base for floating
>> point numbers is 2, that's something you have to check.
>> (POWER6 and z9 has hardware support for base 10 floating point.)
>> -- Lennart
> Well, in light of
> -- We assume that FLT_RADIX is 2 so that we can use more efficient code
> #if FLT_RADIX != 2
> #error FLT_RADIX must be 2
> properFraction (F# x#)
> = case decodeFloat_Int# x# of
> (# m#, n# #) ->
> let m = I# m#
> n = I# n#
> if n>= 0
> then (fromIntegral m * (2 ^ n), 0.0)
> appearing in the RealFrac instance for Float, I thought it would be a safe
> optimisation to use for Float and Double in GHC.Float (oddly, FLT_RADIX ==
> 2 is only used for Float, not for Double).
> I can of course wrap the base 2 code in an "#if FLT_RADIX == 2" and have
> general code for other bases, but as long as the #error stays, that seems
Making the assumption is fine (as we do in the code above), but the
important thing is to make the build fail in a very noisy way if the
assumption turns out to be wrong (as above).
>> On Fri, Oct 8, 2010 at 2:08 PM, Daniel Fischer<daniel.is.fischer at web.de>
>>> 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
>>> and, in the case of truncate, different garbage when the rewrite rule
>>> Prelude GHC.Float> double2Int 1.234e11
>>> 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
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at haskell.org
> Libraries mailing list
> Libraries at haskell.org
More information about the Haskell-Cafe