比较运算符在溢出的情况下如何工作

how does comparison operator works in case of overflow

本文关键字:何工作 工作 情况下 运算符 溢出 比较      更新时间:2023-10-16

我有以下代码:

int main() {
   int64_t val1 = 0x8000000000000000;
   int64_t val2 = 0x1c11223344556677;
   if(val1 > val2) {
      std::cout << "Val1 is greater than val2"<< std::endl;
   }
   else {
      std::cout << "Val2 is greater than val1"<< std::endl;
   }
   return 0;
}

获取代码其他部分的打印。

我想知道在其中一个值超过最大值的情况下,比较运算符或任何算术运算是如何工作的?

根据C++11§5:

如果在表达式求值过程中,结果未在数学上定义或不在其类型的可表示值范围内,则行为未定义。

0x8000000000000000是一个大的无符号整数,9223372036854775808为十进制。

可以存储在64位带符号整数中的最大值,由INT_64_MAX或类似值表示,为9223372036854775807。

该值从无符号到有符号的转换包含在标准n3797 S4.7/3:中

如果目的地类型是有符号的,那么如果可以用目的地类型(和位字段宽度)表示,则该值不变;否则,该值由实现定义。

由于不能如此表示,因此行为是由实现定义的。

在大多数实现中实际发生的情况是,位值将被存储为不变。现在val1的值超出了允许的范围,任何对它的使用都将导致"未定义的行为"。

特别是两个有符号整数之间的比较,其中一个超出了允许的范围,无法可靠地预测。它可能会遵循底层机器硬件中的特定指令,所以你必须检查生成的代码来确定是哪一个。我可以编写代码并告诉你我发现了什么,但对于不同的编译器或处理器,可能会有所不同。

最好的建议是尽可能避免未定义的行为。

在其他情况下,我希望你的意思是大于或等于.

运算器根本不起作用,因为int64_t意味着将值存储在极限(-2^63到2^63-1)中。如果您想要更多的范围,请使用无符号版本。对于更大的范围,使用一些现成的bignum库或自己编写一个。(例如,您可以将大的数字存储在字符串中,比较将变得非常容易)

比较运算符照常工作:在这种情况下,val1将为负(其最高有效位已设置!),因此它将小于val2,后者为正。

#include <iostream>
int main() {
   int64_t val1 = 0x8000000000000000;
   int64_t val2 = 0x1c11223344556677;
   std::cout << "val1: " << val1 << std::endl;
   std::cout << "val2: " << val2 << std::endl;
   if(val1 > val2) {
      std::cout << "Val1 is greater than val2"<< std::endl;
   }
   else {
      std::cout << "Val2 is greater than val1"<< std::endl;
   }
   return 0;
}

输出(视频):

val1: -9223372036854775808
val2: 2022435311251187319
Val2 is greater than val1