Fred said:
I'm using the expression "int a = ceil( SomeDouble )". The man page says
that ceil returns the smallest integer that is not less than SomeDouble,
represented as a double. However, my understanding is that a double has
nonuniform precision throughout its value range. Will a double always be
able to exactly represent any value of type int? Could someone please
point me to an explanation of how this is ensured, given that the details
of a type realization varies with the platform?
Thanks.
Fred
P.S. I am not worried about overflowing the int value range, just about
the guaranteed precise representation of int by double.
Thanks, all, for your replies. They have pointed out a flaw with my own
question. Specifically, it is one thing to ask:
(1) if a double can precisely represent any int.
It is quite another to ask:
(2) if an int(ceil(SomeDouble)) can precisely represent the smallest
integer that is no smaller than SomeDouble, given that SomeDouble is
in the value range of int.
The answer to #1 is clearly no if the mantissa of the double has
"significantly" fewer bits than the int. The reason for "significantly" is
approximate bookkeeping I've walked through; based on Chris's description,
I tried to sanity check this. It starts with the idea that whether a
double can represent any int depends on whether a double can increase in
value by exactly 1 throughout the value range of int. That is, when the
LSB of the mantissa is toggled, does the value of the double change by no
more than 1? For a mantissa of N bits, ignoring the IEEE hidden bit, this
condition is satisfied if scaling due to the exponent (power of 2) is
less-than-or-equal-to 2^N. I'm not talking about how the exponent is
represented in terms of bits; I'm talking about multiplying the mantissa by
2^N, however it is represented in IEEE format. Bascially, the scaling is
such that there are no fractional bits. An exponent value greater than N
yields a scaling that causes the double to increment by more than 1 when
the mantissa increments. Hence, the limiting condition for the double to
have a precision of unity is when the scaling is 2^N. The maximum number
under this condition is when the mantissa is all-ones (N+1 ones including
the hidden bit) i.e. the double has value 2^(N+2)-1. (I'm ignoring the
details to accommodate negative numbers, this might affect the answer by a
bit or so). If all ints fall within this limit, then a double can
represent all ints.
I think the answer to #2 follows from this picture of scaling the mantissa
so that the LSB has unit value. I had to remind myself that the condition
considered in #2 is that SomeDouble is within the value range of int, so
the hazard being tested is not one of overflow. Irrespective of this
condition, however, there are two scenarios which ceil(SomeDouble) can be
split into. One is that the exponent scaling of SomeDouble leaves some
fractional bits, and the other is that it doesn't. If there are some
fractional bits, then the resolution of SomeDouble in that value range is
obviously more precise than a unity step, so integers are precisely
representable, and ceil should return the right value. If there are no
fractional bits, then SomeDouble has an integral value, and passing it
through the ceil function should result in no change, regardless of the
resolution of SomeDouble in that value range i.e. ceil should be able to
return the correct value as a double.
The unintuitive result of this (to me) is that SomeDouble *always* returns
precisely the right answer. Whether it fits into an int is a different
issue (issue#1). I suspect this is what Chris was illustrating.
Comments, confirmations, and corrections welcome.
Fred