在leetcode

时间:2017-01-16 22:36:30

标签: c++ overflow

我试图解决反向整数问题,我们必须记住处理溢出问题。

阅读其他解决方案并试用,我写了我的解决方案

class Solution {
public:
  int reverse(int x) {
  int result = 0;
  int old_result = 0;
  while(x) {
    old_result = result;
    result = result*10 + x%10;
    if ((result-old_result*10)!=x%10)
        return 0;
    x = x/10;
  }
  return result;
  }
};

答案未被接受,因为溢出处理得不好。事实证明正在改变

if ((result-old_result*10)!=x%10)

if ((result-x%10)/10!=old_result)

会让事情奏效。

我觉得这些线都在做同样的检查。不知道为什么一个人通过,一个人失败。

任何人都可以帮忙解释一下吗?

3 个答案:

答案 0 :(得分:1)

  

我觉得这些线都在做同样的检查。不确定为什么一个人通过,一个人失败。

不一定。如果old_result的值超过(或等于)std::numeric_limits<int>::max () / 10 + 1,则表达式old_result*10会溢出,这会给您错误的答案。

整数类型的溢出是未定义的行为。这是完全来自C ++(C ++ 11 / C ++ 14 / C ++ 17)标准草案(我无法访问完整版标准,并且在大多数情况下,它已经足够了) :

  

如果在评估表达式期间,结果未在数学上定义或不在范围内   其类型的可表示值,行为未定义。

if的第二种形式(重新排序)删除了乘法 - 有效地增加了可以在old_result中使用的值范围。

答案 1 :(得分:1)

   result = result*10 + x%10;

   if ((result-old_result*10)!=x%10)
   // or
   if ((result-x%10)/10!=old_result)

result*10 + x%10;之后编码时,两者都很糟糕,因为溢出可能已经发生。

对于行为良好的代码,应避免

int溢出。

不依赖于溢出行为,而是在计算它之前检测result*10 + x%10是否会溢出。

  // for positive numbers
  int max = std::numeric_limits<int>::max
  while(x) {
    int digit = x%10;
    if (result >= max/10 && (result > max/10 || digit > max%10)) {
      Overflow();
    }
    result = result*10 + digit;
    x = x/10;
  }

答案 2 :(得分:0)

请注意,带有签名号码的溢出是特定于实现的 UB,因此我建议使用unsigned代替。然后考虑它使用类似的属性而不是unsigned,并假设result = result*10 + x%10;溢出。然后:

result -= old_result * 10;

&#34;回复&#34;以同样的方式溢出。

而以下是真的

(result - x % 10) == old_result * 10; // With possible overflow in both side.

双方10除以仅使用简化

来消除溢出
(result - x % 10) / 10 == old_result;
// overflow on left side (before division). No overflow on right side.