Take the 2-minute tour ×
int main(int argc, char *argv[])
    uint64_t length = 0x4f56aa5d4b2d8a80;
    uint64_t new_length = 0;

    new_length = length + 119.000000;

    printf("new length  0x%"PRIx64"\n",new_length);

    new_length = length + 238.000000;


    return 0;

With the above code. I am adding two different double values to a unsigned 64-bit integer.I am getting the exact same result in both the cases.The output of the program is show below

new length  0x4f56aa5d4b2d8c00
new length  0x4f56aa5d4b2d8c00

I would expect two different results but that is not the case.I have also tried type-casting the uint64_t value to a double as in

new_length = (double)length + 119.000000;

But this too doesn't seem to help.Any idea on what might be the problem?

share|improve this question
possible duplicate of Why is this true? –  In silico Mar 7 '12 at 3:49
add comment

2 Answers

up vote 3 down vote accepted

Floating point arithmetic is not precise. As numbers get bigger, the accuracy of lower digits is reduced.

0x4f56aa5d4b2d8a80 is a Very Large Number.

What is happening in

new_length = length + 119.000000;

Is that length + 119.000000 is getting cast to a double, to do the addition. That double is rounded, rather dramatically, because it's so large. It is then cast again to the integral type uint64_t when it is assigned to new_length.

When you call

new_length = length + 238.000000; 

It happens that the rounded result ends up being the same.

What you really want to do is

new_length = length + (uint64_t)238.0; 

That will give you the answer you want. It will initially cast the double to an integral type, which is added precisely.

share|improve this answer
Floating-point is precise. You can repeat the same experiment over and over and get identical results. Those results may not align with your expectations based on your experience with the real numbers, but they are certainly precise. –  Stephen Canon Mar 7 '12 at 17:37
add comment

Since you adding a floating-point operand, both operands are implicitly cast to double and the addition is done using floating-point arithmetic.

However, double doesn't have enough precision to exactly hold either of the following values:

0x4f56aa5d4b2d8a80 + 119.0  (requires 63 bits of precision)

 <-------------------63 bits of precision---------------------->

0x4f56aa5d4b2d8a80 + 238.0  (requires 62 bits of precision)

 <-------------------62 bits of precision--------------------->

Standard IEEE double precision only has 53 bits of precision.

The result is that both of them get rounded to the same final value of:

0x4f56aa5d4b2d8c00  (53 bits of precision)

 <-----------------53 bits of precision-------------->

If you want to avoid this rounding, you should avoid floating-point arithmetic altogether by casting the operands to integer. (or just using 119 and 238 instead)

share|improve this answer
add comment

Your Answer


