如何使变量不超过其类型的大小限制
how to make a variable not exceed the size limit of its type?
所以我想知道如何使变量不超过其数量限制。
例如:
int x;
x的大小是四个字节的
由于已签名,它从(−2147483648)开始到(2147483647)
因此,如果输入大于2147483647,它将不会注册,我想防止程序让大于其数字限制的数字输入
这里有一个代码会遇到这个问题:
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呢?
可移植且明显但不令人满意的答案是,您必须事先检查操作数:
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
语句来执行。
您要查找的单词是"溢出"。
自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
这很好地涵盖了主题。然而,如果你想要一个快速而肮脏的解决方案,你总是可以得到双倍的结果,四舍五入,并检查它是否会导致溢出。如果没有,则强制转换为integer并使用它。如果有,则可以抛出错误,例如:
#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.
- 如何确保接受的C++模板类型使运算符重载?
- 如何使自定义类型在unordered_map中用作键
- 如何使映射键具有两种不同的数据类型?
- 如果可推导类型上有替换,可变参数模板类型推导会使编译器崩溃
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 使模板函数按函数参数选择类型
- 将 unordered_map 与 Catch2 谓词一起使用时类型不匹配
- 如何使虚函数接受仅在派生类中定义的数据类型?
- 不能使这种类型的"void(C::* volatile)(int) const "在参考手册C++示
- C++如何使虚拟函数返回任何类型的指针
- 推荐的方法在不初始化值的情况下使数组类型为 std::unique_ptr?
- 将运算符<<与隐式转换的非基本数据类型一起使用时出错
- decltype(auto) 是否使尾随返回类型过时?
- 如何包装对象,使它们成为无法交互的单独类型?
- 将分配的内存与基本数据类型一起使用时,是否需要新放置? std::complex?
- Doxygen,当参数类型定义使签名相同时,如何拆分函数文档?
- 什么类型会使"std::has_unique_object_representations"返回 false?
- 我如何使用类型特征使这种数组到指针的转换明确
- C++:"such strings"类型。使像 fun( "str" ) 一样的函数调用工作
- 自定义类型,类型转换使运算符发生冲突