C++大量(无符号长长)的溢出检测
C++ overflow detection for large numbers (unsigned long long)
我正在处理大整数(无符号长整型),需要防止溢出情况。无论是否实际存在异常,代码都会引发异常:
try
{
unsigned long long y = std::numeric_limits<unsigned long long>::max() - 2;
unsigned long long z = 1;
int size = - 1;
if((y+z) ^ y < 0) //If y+z causes overflow its sign will be changed => y and (y+z) will have opposite signs
throw std::overflow_error("overflow of y+z");
//int* myarray= new int[size]; VS Debug Library catches it earlier than catch()
printf("%dn", y*(y+z));
}
catch(exception& e)
{
cout << e.what() << endl;
}
由于它已经是最大的数据类型(64 位),因此没有空间升级到更大的数据类型。
新代码:
try
{
unsigned long long int y = std::numeric_limits<unsigned long long int>::max() - 2;
unsigned long long int z = std::numeric_limits<unsigned long long int>::max() / 2;
unsigned long long delta = std::numeric_limits<unsigned long long int>::max() - y;
int size = - 1;
if(z > delta) //If y+z causes overflow its sign will be changed => y and (y+z) will have opposite signs
throw std::overflow_error("overflow of y+z");
//int* myarray= new int[size]; VS Debug Library catches it earlier than catch()
printf("%dn", (y+z));
}
catch(exception& e)
{
cout << e.what() << endl;
}
y < 0
总是假的,任何 xor 0 将永远是那个东西(您是否错过了<
的评估优先级高于 ^
?
因此,除非 mod x + y
<the max value>
恰好等于 0,否则您将抛出(并且可能总是在实践中抛出,除非您人为地设计了特定的输入)。
也许你的意思是这样的:if((std::numeric_limits<unsigned long long>::max() - y) < z) throw ...;
您有两个问题。主要是运算符优先级:<
高于^
。这是在启用所有警告的情况下进行编译的一个很好的原因,因为 gcc 和 clang 都给了我一个关于这个表达式的警告并建议括号!
编译器评估的表达式实际上是:
if ( (y+z) ^ (y < 0) )
由于y < 0
的计算结果为 0
,这只是:
if (y+z)
这显然是true
.但即使括号正确,如:
if (((y+z) ^ y) < 0) { ... }
这个表达方式false
微不足道。它仍将具有永远不会评估为 < 0
的 unsigned long long
型。
相关文章:
- 将整型转换为浮点型时检测溢出
- 我很难理解这些关于检测整数溢出的评论
- 检测 32 位整数溢出
- 编译器是否有可能检测整数溢出或其他数据类型溢出的可能性
- 在发布模式下检测到缓冲区溢出 - linux
- 静态分析,用于检测 Visual Studio C++ 2012 上的缓冲区溢出
- 检测输入中的整数溢出
- 检测到缓冲区溢出
- C++大量(无符号长长)的溢出检测
- 0x00363A09处出现未处理的异常,堆栈cookie检测代码检测到基于堆栈的缓冲区溢出
- 如何为大型项目制作一个简单的工具来检测Linux中的双倍空闲或内存溢出
- 检测旧GLIBC版本的堆栈溢出
- 整数幂元函数:检测整数溢出
- 检测 Linux 上多线程C++应用程序中的堆栈溢出/覆盖
- 如何在命令行应用程序中检测堆栈溢出.在macos上用C++编写
- 溢出检测
- 冲突检测期间发生堆栈溢出错误
- 从istream中读取int,检测溢出
- UDP套接字缓冲区溢出检测
- 如何检测双精度浮点溢出和下溢