所以我想知道如何使变量不超过其数量限制。
例如:
int x;
x的大小是四个字节
并且自签署后,它从(-2,147,483,648)开始到(2,147,483,647)
所以如果输入大于2,147,483,647则不会注册,我想阻止程序输入大于其数量限制的数字
这是一个会遇到这个问题的代码:
int x[3];
x[0] = 12;
x[1] = 642;
x[2] = 800000000;
for (int z = 0;z < 3;z++)
{
x[z] = x[z] * 3;
}
那么,如果结果大于变量类型的数量限制,我将如何防止x [z]将其自身乘以3?
答案 0 :(得分:1)
你要找的词是“溢出”。
自GCC 5以来,有内置函数可以检测到这一点:https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
对于以前的版本,您必须找到另一个实现 - 在某处可能存在polyfill。
对于排名大于或等于int
的有符号整数,您也可以使用-fsanitize=signed-integer-overflow
进行编译。
编辑:如果输出和两个输入都是相同的类型,那么LKML上有一个补丁:https://lkml.org/lkml/2015/7/19/358
答案 1 :(得分:1)
便携且明显但不令人满意的答案是你必须事先检查你的操作数:
int x[3];
x[0] = 12;
x[1] = 642;
x[2] = 800000000;
for (int z = 0; z < 3; z++)
{
if (x[z] < std::numeric_limits<int>::max() / 3 &&
x[z] > std::numeric_limits<int>::min() / 3)
{
x[z] = x[z] * 3;
} else {
std::cout << "Error" << std::endl;
}
}
不幸的是,没有可移植的内置工具来检测/防止溢出,当它们发生时/之后,但你可以查看clang的清洁剂(我相信也是gcc)这些基本上会自动检测你的代码与那些检查例如如果发生溢出,则终止程序。
如果您希望仅在调试模式下进行这些检查,则可以将其作为assert
的一部分而不是if
语句执行。
答案 2 :(得分:-1)
This很好地涵盖了这个主题。但是,如果你想要一个快速而肮脏的解决方案,你总是可以得到一个双倍的结果,然后检查它是否会导致溢出。如果没有,则转换为整数并使用它。如果是,则可以抛出错误,例如:
#include <iostream>
#include <cassert>
#include <limits>
using namespace std;
int main()
{
int xOriginal=1000000000;
int xFinal=0;
for (int i=0;i<1000;++i){
double temp_result=i*(double)xOriginal;
if (temp_result<std::numeric_limits<int>::max()
&& temp_result>std::numeric_limits<int>::min()){
xFinal=(int)temp_result;
cout <<"new x is : "<<xFinal <<endl;
}else{
assert(!"Integer overflow");
}
}
}
此代码的输出为:
new x is : 0
new x is : 1000000000
new x is : 2000000000
a.out: test6.cpp:19: int main(): Assertion `!"Integer overflow"' failed.