Блог пользователя XiangXunyi

Автор XiangXunyi, история, 3 месяца назад, По-английски

As the title, 1e18 + 1 == 1e18 in C++.

This is because the double type stores the first 53 binary bits of a number. So the number 1 will be ignored.

And most of submissions which fst on test 13 of problem C of edu round 187 are for this reason.

UPD: I collected some suggestions from the comments:

  1. Use 1000000000000000001 (I do not suggest it because it is prone to errors.)
  2. Use (long long)(1e18) + 1
  3. Use 1e18L + 1
  4. Use 1'000'000'000'000'000'001LL
  • Проголосовать: нравится
  • +248
  • Проголосовать: не нравится

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by XiangXunyi (previous revision, new revision, compare).

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится +21 Проголосовать: не нравится

 I hate my life

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится -20 Проголосовать: не нравится

f*ck this shit

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I got wrong for this :(

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится +23 Проголосовать: не нравится

Just use LLONG_MAX, it's in the c++ standard and expressive!

reference

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

laugh as never use expressions like that.i only use 100000000... despite that the work of counting zeros is a bit annoying

»
3 месяца назад, скрыть # |
Rev. 3  
Проголосовать: нравится 0 Проголосовать: не нравится

hi! i think using implicit conversion is a good enough fix for this i.e. using something like: -

const long long INF = 1e18

i used the above mentioned declaration for my binary search bounds, and it AC'ed without any issues.

although i do believe the best way to avoid such issues is to use integer literals: -

const long long INF = 1000000000000000000LL
»
3 месяца назад, скрыть # |
 
Проголосовать: нравится +15 Проголосовать: не нравится

u can just force it back to long long to avoid this problem, like this const long long INF = (long long) 1e18;

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится +7 Проголосовать: не нравится

There is 1e18l in g++

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится -8 Проголосовать: не нравится

你说的很对!

»
3 месяца назад, скрыть # |
Rev. 2  
Проголосовать: нравится +13 Проголосовать: не нравится

I hate this type of bug. That's I always initialize long long with a loop to make sure the value reach exactly the correct limit. For example, to initialize with 1e18 + 1 it suffices to do:

ll MAX = 1e9;
while(MAX <= 1e18 + 1) MAX++;
MAX--;

Note the optimization that I initialize with MAX = 1e9 instead of MAX = 0 to save time. This works because 1e9 is represented exactly without errors.

This is a powerful technique which can be used to find floor of various function like sqrt or log. For example, to find largest long long x such that x * x <= N, I always write it as follows:

ll x = sqrt(N) - 1;
while (x * x <= N) x++;
x--;

This allows to compute sqrt in O(1) while I can be sure the value is correct without any floating-point shenanigans. Similarly for logs, just use while ((1 << x) <= N) x++;

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by XiangXunyi (previous revision, new revision, compare).

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится +8 Проголосовать: не нравится

use 1000000009 and 1000000000000000018, This can avoid counting the wrong number of 0.

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

only after seeing testcase 13 where i got wrong then only i able to figure out this

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

how about using (1LL << 60)

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится +11 Проголосовать: не нравится

You can use apostrophes in C++ integer literals, which is sometimes useful when you want to specify large constants. In this case it would be 1'000'000'000'000'000'001LL.

»
3 месяца назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

Those who use hex numbers to define infinity.

const int inf_32 = 0x3f3f3f3f;
const long long inf_64 = 0x3f3f3f3f3f3f3f3f;
»
3 месяца назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by XiangXunyi (previous revision, new revision, compare).