【问题标题】:How to compare sum of two int64 with INT64_MAX?如何将两个 int64 的总和与 INT64_MAX 进行比较?
【发布时间】:2022-01-09 02:45:21
【问题描述】:

我知道大于INT64_MAX的数字会环绕负数,那么当sum溢出时如何比较,即sum大于INT64_MAX

#include <iostream>

using namespace std;

int main() {
  int64_t a = INT64_MAX;
  int64_t b = 1;
  // cin >> a >> b;
  if (a + b <= INT64_MAX) {
    cout << "Yes" << endl;
  } else {
    cout << "No" << endl;
  }
  return 0;
}

【问题讨论】:

  • 我知道大于 INT64_MAX 的 int64 会环绕负数 不一定。 uint64_t 将回绕为 0。但有符号整数类型的溢出行为是未定义的。
  • I know int64 greater than INT64_MAX will wrap around negative, - 你知道错了。这是未定义的行为。
  • INT64_MAX中减去一个操作数,看看结果是否大于第二个操作数。
  • 预测a + b是否会溢出的常用方法是检查MAX - a是否大于b,尽管如果ab可能为负数,你必须小心.
  • 您有 2 个溢出需要避免,正面是 INT64_MAX,反面是 INT64_MIN

标签: c++ integer


【解决方案1】:

比较前先检查a + b看会不会溢出。

int is_overflow(int64_t a, int64_t b) {
  if (((b > 0) && (a > (INT64_MAX - b))) ||
      ((b < 0) && (a < (INT64_MIN - b)))) {
    return 1;
  }
  return 0;
}

【讨论】:

    【解决方案2】:

    在加法之前先将bINT64_MIN - aINT64_MAX - a 进行比较,以防止有符号整数未定义行为 (UB) 溢出。

    // True when sum overflows.
    bool is_undefined_add64(int64_t a, int64_t b) {
      return (a < 0) ? (b < INT64_MIN - a) : (b > INT64_MAX - a);
    }
    

    最坏情况:2 次比较。

    对于div, mul, sub

    【讨论】:

    • 为什么不返回bool 而不是int
    • @AyxanHaqverdili 没有什么特别的原因,除了在 C 中它是源自代码的 #include 少一个。改为bool
    • 在 C 中,您始终可以使用 _Bool 而不包含任何内容。但它对 C++ 的移植性较差。
    猜你喜欢
    • 2015-10-29
    • 1970-01-01
    • 2014-10-27
    • 2019-05-21
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 2021-06-02
    • 2016-12-25
    相关资源
    最近更新 更多