You can compare some different doubles like this:
double a = BitConverter.ToDouble(new byte[] { 156, 153, 153, 153, 153, 153, 33, 64, }, 0);
double b = BitConverter.ToDouble(new byte[] { 155, 153, 153, 153, 153, 153, 33, 64, }, 0);
double c = BitConverter.ToDouble(new byte[] { 154, 153, 153, 153, 153, 153, 33, 64, }, 0);
double d = BitConverter.ToDouble(new byte[] { 153, 153, 153, 153, 153, 153, 33, 64, }, 0);
double e = BitConverter.ToDouble(new byte[] { 152, 153, 153, 153, 153, 153, 33, 64, }, 0);
Console.WriteLine(a.ToString("R"));
Console.WriteLine(b.ToString("R"));
Console.WriteLine(c.ToString("R"));
Console.WriteLine(d.ToString("R"));
Console.WriteLine(e.ToString("R"));
Using the format string "R"
shows extra digits but only if necessary to distinguish between other representable System.Double
.
Addition (explanation of the bytes): 64
and 33
give the sign, magnitude and first (most) significant bits of the number 8.8
. Since 8.8
is a fraction with a small denominator (the 5 in 44/5), it is not surprising that the rest of the bits repeat over and over with a short period. To get the exact 8.8
, the 153s would have to continue forever. But there's only room for eight bytes in a double
. Therefore we need to round. Rounding to 154
gives the closest value because the next "term" (153
) is closer to 256
than to 0
. Therefore c
is the most precise representation possible.
When you look through the output of the above code, you see that c
is just output as 8.8
even when we used the "R"
format string. But you know that c
is halfway between b
and d
(and also halfway between a
and e
), and from that you can easily estimate that the "true" decimal value most be very near 8.8000000000000007
.