关于 long long 溢出
查看原帖
关于 long long 溢出
138400
chenxia25楼主2023/3/28 13:56

对于这题的主流做法,容易构造出数据使得懒标记爆 long long,只要反复 * 1000000000 然后 - 999999999

6 1 1000000000
* 1000000000
- 999999999
* 1000000000
- 999999999
* 1000000000
- 999999999
1
1

虽然这确实触发了 ub(开启 -fsanitize=undefined 即可检测),但在大部分编译器的大部分情况下 long long 溢出都是保持模 2642^{64} 的正确结果的,而这题只是懒标记会溢出,要访问的真实值不会溢出,所以就很难卡。

long long 溢出的一个表现是大小判断会不对,以下这段代码在开 O2 时可能会有奇怪的输出。

#include <bits/stdc++.h>
using namespace std;

int main() {
  long long a = 1;
  for(int i = 1; i <= 10; ++i) {
    a *= 1000000000;
    if(a > 0) cout << a << " is positive\n";
  }
  return 0;
}

因为这题确实要判断大小,我试图用这个现象构造 hack 数据,但还是失败了。因为 ub 毕竟是 ub,根本就无法预测结果。

一个比较对的写法是用 unsigned long long 自然溢出。还是建议大家写没有 ub 的代码。

2023/3/28 13:56
加载中...