Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double overflow?

Tags:

c++

overflow

I have always wondered what happens in case a double reaches it's max value, so I decided to write this code:

#include <stdint.h>
#include <iostream>
#define UINT64_SIZE 18446744073709551615
int main() {
    std::uint64_t i = UINT64_SIZE;
    double d1 = ((double)(i+1)) / UINT64_SIZE; 
    double d2 = (((double)(i)) / UINT64_SIZE)*16;
    double d3 = ((double)(i * 16)) / UINT64_SIZE;

    std::cout << d1 << " " << d2 << " " << d3; 
}

I was expecting something like this:

0 16 0 

But this is my output:

0 16 1 

What is going on here? Why are the values of d3 and d1 different?

EDIT:

I decided to change my code to this to see the result:

#include <stdint.h>
#include <iostream>
#define UINT64_SIZE 18446744073709551615
int main() {
    std::uint64_t i = UINT64_SIZE;
    double d1 = ((double)(i+1.0)) / UINT64_SIZE; //what? 
    double d2 = (((double)(i)) / UINT64_SIZE)*16;
    double d3 = ((double)(i * 16.0)) / UINT64_SIZE;

    std::cout << d1 << " " << d2 << " " << d3; 
}

The result I get now is this:

1 16 16 

However, shouldn't d1 and d3 still be the same value?

like image 256
Anonymus Avatar asked Mar 26 '26 23:03

Anonymus


1 Answers

double overflows by loosing precision, not by starting from 0 (as it works with unsigned integers)

d1

So, when you add 1.0 to very big value (18446744073709551615), you're not getting 0 in double, but something like 18446744073709551610 (note last 10 instead of 15) or 18446744073709551620 (note last 20 instead of 15), so - less significant digit(s) are rounded.

Now, you're dividing two almost identical values, result will be either 0.9(9)9 or 1.0(0)1, as soon as double cannot hold such small value - again it looses precision and rounds to 1.0.

d3

Almost the same, when you multiple huge value by 16 - you're getting rounded result (less significant digits are thrown away), by diving it - you're getting "almost" 16, which is rounded to 16.

like image 88
Iłya Bursov Avatar answered Mar 29 '26 11:03

Iłya Bursov