【问题标题】:C++ Preventing Int Overflow for addition?C++ 防止 Int 溢出添加?
【发布时间】:2021-05-25 05:53:04
【问题描述】:

在我的 C++ 代码中:

int c=(a+b)/2;

我确定最终结果不会导致整数溢出,但这不能保证 (a+b)

这是我的错误信息:

第 20 行:字符 27:运行时错误:有符号整数溢出:1063376696 + 2126753390 无法在类型“int”中表示 (solution.cpp) 摘要:UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:31:27

我该如何解决这类问题?

【问题讨论】:

  • 大概你的意思是整数溢出,而不是堆栈溢出。如果 a 和 b 是整数并且相加时可以大于 2^31,那么您需要更大的数据类型,例如 int64
  • 第 20 行:字符 27:运行时错误:有符号整数溢出:1063376696 + 2126753390 不能用类型“int”表示(solution.cpp) 摘要:UndefinedBehaviorSanitizer:未定义行为 prog_joined.cpp:31: 27
  • @bennji_of_the_overflow 没有帮助,请参阅我的错误消息
  • @daniel “查看我的错误消息” - 你的意思是屏幕上我们看不到的那个?我们不是介意读者。错误消息属于您的问题。不管怎样,int c = a + (b-a)/2;,在b >= a保水的前提下,会防止a+b的添加剂溢出。
  • @WhozCraig 太棒了!

标签: c++ integer overflow


【解决方案1】:

您可以使用 64 位整数进行操作,然后再转换回 32 位。

int c = int((std::int64_t(a) + std::int64_t(b)) / 2);

【讨论】:

    【解决方案2】:
    1. 使用避免溢出的标准库函数:

      std::midpoint(a, b);
      
    2. 转换为更大的类型,避免溢出:

      static_cast<int>((static_cast<std::int64_t>(a) + static_cast<std::int64_t>(b))/2);
      
    3. 使用特定于编译器的标志来检测它,例如-ftrapv,或内置插件,例如__builtin_add_overflow:

      if (__builtin_add_overflow(a, b, &result))
          throw std::out_of_range("overflow");
      
    4. 以避免溢出的方式执行计算(将其分解为案例并找出在每种情况下避免溢出的方法):

      using U = unsigned int;
      return a>b ? a-(static_cast<U>(a)-b)/2 : a+(static_cast<U>(b)-a)/2;
      

    https://godbolt.org/z/T3rPdq

    【讨论】:

      【解决方案3】:

      只需使用 int c=a+(b-a)/2;如果 a 和 b 都是正数。否则,您可以使用上述方法

      【讨论】:

      • 欢迎来到 Stackoverflow。我认为答案可能会有所改善。有解释,格式化等。但仍然感谢有用的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-22
      • 1970-01-01
      相关资源
      最近更新 更多