Why does the following code output 1000000000000000000 and not 1000000000000000001?
#include <bits/stdc++.h>
using namespace std;
long long inf = 1e18+1;
int main() {
cout << inf << '\n';
}
# | User | Rating |
---|---|---|
1 | tourist | 3985 |
2 | jiangly | 3814 |
3 | jqdai0815 | 3682 |
4 | Benq | 3529 |
5 | orzdevinwang | 3526 |
6 | ksun48 | 3517 |
7 | Radewoosh | 3410 |
8 | hos.lyric | 3399 |
9 | ecnerwala | 3392 |
9 | Um_nik | 3392 |
# | User | Contrib. |
---|---|---|
1 | cry | 169 |
2 | maomao90 | 162 |
2 | Um_nik | 162 |
4 | atcoder_official | 161 |
5 | djm03178 | 158 |
6 | -is-this-fft- | 157 |
7 | adamant | 155 |
8 | awoo | 154 |
8 | Dominater069 | 154 |
10 | luogu_official | 150 |
Why does the following code output 1000000000000000000 and not 1000000000000000001?
#include <bits/stdc++.h>
using namespace std;
long long inf = 1e18+1;
int main() {
cout << inf << '\n';
}
Name |
---|
If I were to guess it is some weird floating point precision error? This code works as expected
It works! Thank you!!
Not 100% sure, but
1e18
is a floating point number. When the right-hand side is being computed,1
is added to1e18
, which means the resulting floating point number will require 18 digits of precision, which was most probably truncated or rounded because no floating point types can handle it. Then, it is converted tolong long
.Also take a look at this:
Output:
As pointed out by tn757, the fix is to typecast
1e18
tolong long
first so we don't have to deal with floating point precision.I'm very surprised by the results from 1e18+100! Thanks!
The reason why the output of the code is 1000000000000000000 and not 1000000000000000001 is due to an overflow error.
In C++, the
Nice try, ChatGPT!
99% probability for AI https://copyleaks.com/ai-content-detector
This answer is also plainly wrong, 1e18 is clearly smaller than 9e18. 2^63 — 1e18 = ~2^63.
This comment really showcases ChatGPT's Codeforces rating of 392.
long double
is more precise. You can get it by addingL
at the end of a numeral.long long inf = 1e18L + 1;
Double has 8 bytes, long long has 8 bytes. Can double represent all the integers that can be represented in long long? No, because how would it represent fractional numbers plus all the integer numbers with the same amount of memory? Double has 15 decimal digits of precision, which means it can represent integers up to 1e15. The next smallest double after 1e18 is 1e18+1000
float
can store all positive integers up to (and including) $$$2^{24} \approx 1.7 \cdot 10^7$$$.double
can store all positive integers up to (and including) $$$2^{53} \approx 9 \cdot 10^{15}$$$.long double
can store all positive integers up to (and including) $$$2^{64} \approx 1.8 \cdot 10^{19}$$$.After this limit, there are still many integers that can be represented as floating point numbers, but most integers cannot. For example take
float
and the integers $$$2^{24} + 1$$$ and $$$2^{24} + 2$$$. $$$2^{24} + 1$$$ cannot be stored in afloat
, but $$$2^{24} + 2$$$ can.So now let us analyze
long long inf = 1e18+1;
. By the default behaviour of C++1e18
is of the typedouble
, and it turns outdouble
can store $$$10^{18}$$$ (even though it is above the limit), so no rounding is happening here. However $$$10^{18}+1$$$ happens to not be storeable in adouble
, so it will round the sum to the closest representable floating point value, which is $$$10^{18}$$$. So the conclusion is thatinf
will get the value $$$10^{18}$$$.One fix is to do
long long inf = 1e18L+1;
, which would make1e18L
along double
.long double
s can handle any integer calculation $$$\leq 2^{64}$$$ no problems. So this timeinf
will become10^{18} + 1
.