关于int类型超出数据范围的一点讨论
关于int类型超出数据范围的一点讨论
lc第150题,题目本身不难,使用堆栈去实现。但是实现的过程中会有int超出数据范围的错误: 以下是我的代码:
public: int evalRPN(vector<string>& tokens) { stack<int>s; // ??????? int n=tokens.size(); for(int i=0;i<n;i++) { if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/"){ int temp1=s.top(); s.pop(); int temp2=s.top(); s.pop(); if(tokens[i]=="+"){ s.push((long long)temp1+temp2); }else if(tokens[i]=="*"){ s.push((long long)temp2*temp1); //????????? }else if(tokens[i]=="/"){ s.push((long long)temp2/temp1); }else{ s.push((long long)temp2-temp1); } continue; }else{ s.push(atoi(tokens[i].c_str())); } } return s.top(); } };
出现错误的原因是我定义了一个存放int数据类型的堆栈,当结果为2147483648时就会出错,因为超出了int类型的表示范围,这些大家应该也都清楚。 然后我把数据类型强转为long long(如上面的代码所示),最终顺利通过。
好了,介绍完毕,正当我要进行下一道题的时候,我突然被一个问题所困扰: 在这一步代码中 s.push((long long)temp2*temp1); 其中的(long long)temp2*temp1 肯定是一个long long数据类型,这一点大家应该没什么疑问,但是我定义的stack是一个int类型啊,把一个long long类型的数据 push到stack中居然还能顺利通过?!
基于此,我在vs中进行了测试并且查阅了一些资料,我的测试代码:
{ stack<int>s; int a = 1073741824; s.push((long long)a*2); s.push((long long)a * 2 + 1); s.push((long long)a*2+2); cout<<s.top()<<endl; s.pop(); cout <<s.top()<< endl; s.pop(); cout<<s.top()<<endl; }
我的意图是把一个long long 类型的数据push到int的stack中会怎样,结果如下: 也就是说,虽然2147483648没有超出long long的范围,但是超出了int的范围,所以对于stack.top(),得到的数据仍然是产出范围后失效的数字。
当int超出范围时,比如2147483648时,会得到-2147483648 当继续增大int数据时,得到的内容会在原来的基础上加1,比如2147483649,得到的就是-2147483647;2147483650,得到的就是-2147483646
好了,找到了问题的关键,那么回过头来再看这道题: 是不是就离了个大谱。
− 128 ∗ ( − 128 ) = 16384 16384 ∗ ( − 128 ) = − 2097152 − 2097152 ∗ ( − 128 ) = 268435456 268435456 ∗ 8 = 2147483648 此时超出范围, p u s h 到 s t a c k 中后再取出来应该已经变成了 − 2147483648 − 2147483648 ∗ ( − 1 ) = 2147483648 -128*(-128)=16384\16384*(-128)= -2097152\-2097152*(-128)=268435456\268435456*8=2147483648 此时超出范围,push到stack中后再取出来应该已经变成了-2147483648\-2147483648*(-1)=2147483648 −128∗(−128)=1638416384∗(−128)=−2097152−2097152∗(−128)=268435456268435456∗8=2147483648此时超出范围,push到stack中后再取出来应该已经变成了−2147483648−2147483648∗(−1)=2147483648 结果应该是2147483648才对!
所以呢,还是希望lc的工作人员们细心排查bug,不然会误导很多人呀。 如果我的分析有误,也还请大佬批评指正!!!