繁体   English   中英

大量C ++溢出检测(unsigned long long)

[英]C++ overflow detection for large numbers (unsigned long long)

我正在处理大整数(无符号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("%d\n", 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("%d\n", (y+z));
}
catch(exception& e)
{
    cout << e.what() << endl;
}

y < 0始终为false,xor 0始终为该事物(您是否错过了<的计算优先级高于^ ?)。

因此,除非x + y mod <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 它仍然具有unsigned long long类型,永远不会评估为< 0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM