如何使变量不超过其类型的大小限制?

时间:2016-05-02 22:37:03

标签: c++

所以我想知道如何使变量不超过其数量限制。

例如:

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?

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.