Another kind of rounding can occur when a floating number is
converted between different formats, for example with
processors that internally use a higher precision.
Consider the following two almost identical programs.
---------------------------------------------
small powerOf2 exp
| powerOf2 > 0.0
= small (powerOf2 / 2.0) (exp - 1)
| otherwise
= exp
main
= print (small 1.0 0)
---------------------------------------------
small powerOf2 exp
| (\x->x) powerOf2 > 0.0
= small (powerOf2 / 2.0) (exp - 1)
| otherwise
= exp
main
= print (small 1.0 0)
---------------------------------------------
In the current Clean implementation on Wintel platforms the
first programs prints -16446 and the second -1075. The reason
is that in the first program the powerOf2 argument is passed
in a floating point register (double-extended float). In the
second program the identity (with type a -> a) will get its
argument from the heap (extended float).
There's a trade-off here between precision, efficiency and
referential transparency.
Cheers,
Ronny Wichers Schreur