std.conv.to vs. casting
Ali Çehreli
acehreli at yahoo.com
Thu Jul 4 10:13:45 PDT 2013
On 07/04/2013 09:43 AM, Joseph Rushton Wakeling wrote:
> On 07/04/2013 06:16 PM, Ali Çehreli wrote:
>> I am commenting without fully understanding the context: Both size_t
and double
>> are 64 bit types on a 64-bit system. double.mant_dig being 53,
converting from
>> size_t to double loses information for many values.
>
> Oh, bugger. You mean that because it needs space to store the
exponent, it has
> a reduced number of significant figures compared to size_t?
Exactly.
>> import std.stdio;
>> import std.conv;
>>
>> void main()
>> {
>> size_t i = 0x8000_0000_0000_0001;
>> double d0 = i.to!double;
>> double d1 = cast(double)i;
>>
>> writefln("%s", i);
>> writefln("%f", d0);
>> writefln("%f", d1);
>> }
>>
>> Prints
>>
>> 9223372036854775809
>> 9223372036854775808.000000
>> 9223372036854775808.000000
>
> Don't understand why the error arises here, as the number of
significant figures
> is the same for all the numbers ... ?
It is about the difference between the significant number of bits. The
size_t value above uses bits 63 and 0, a range of 64 bits. double's
53-bit mantissa has no room for bit 0.
In contrast, the following size_t value can be represented exactly in a
double because its representation uses only 53 bits:
import std.stdio;
import std.conv;
void main()
{
size_t i = 0x001f_ffff_ffff_ffff;
double d = i.to!double;
writefln("%s", i);
writefln("%f", d);
}
Prints:
9007199254740991
9007199254740991.000000
However, set any one of the currently-unset upper 11 bits (64 - 53 ==
11), and you get an inexact conversion.
Ali
More information about the Digitalmars-d-learn
mailing list