首页 > 解决方案 > 如何控制从 long 到 int 的隐式转换?

问题描述

我正在研究这个 LeetCode 问题,取一个整数并反转它,因为反转的 in 在有符号的 32 位范围内,在这种情况下我们应该返回 0。

这段代码就是这样做的,即使是像 1534236469/-1534236469 这样的数字。除非遇到棘手的数字,例如 -2147483648,它不会将其识别为超出范围,而是返回 8 而不是 0。

我知道这不是最干净的代码,但你能帮我认出我错过了什么吗?

#include<iostream>
#include<limits>
using namespace std;

class Solution {
public:
    int reverse(int x) {
        int a, r, y;
        string num, fnum;
        a = abs(x);
        try{
            while(a != 0){
                r = a % 10;
                a = a / 10;
                num = to_string(r);
                fnum = fnum + num;
                y = stoi(fnum);
            }
        } catch(out_of_range& oor){
            return 0;
        }
        if(x==0){
            return 0;
        } else if (x<0){
            return -y;
        } else {
            return y;
        }
    }
};

int main(){
    Solution mine;
    cout << mine.reverse(-2147483648);
}

标签: c++

解决方案


[...] 当涉及到像 -2147483648 这样的棘手数字时,它不会将其识别为超出范围,而是返回 8 而不是 0。

这个数字很“棘手”,因为它在您的环境中等于std::numeric_limits<int>::min()并且给定 type 的二进制补码表示int,它发生了std::abs(-2147483648) == -2147483648.

接下来在您的(人为的,我必须说,这里不需要使用字符串)代码中,该行将num = to_string(r);导致num = "-8",因此循环将组成一个字符串,如"-8-4-6-3-8-4-7-4-1-2".

当应用于这样的字符串时,不会抛出异常,它只是停止解析(您会通过传递和检查它的其他参数来注意到它)。stoi

如果您想检查结果是否超出范围int,您可以在本地使用更宽的类型(例如)并在计算long long检查边界或继续使用,但在任何计算之前将所有中间值与限制进行比较。int


推荐阅读