我有以下代码:
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;
}
获取其他部分代码的print。
我想知道如果其中一个值超过最大值,比较运算符或任何算术运算如何工作?
答案 0 :(得分:4)
根据C ++11§5:
如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,行为未定义。
答案 1 :(得分:4)
值0x8000000000000000
是一个大的无符号整数,9223372036854775808作为小数。
可以存储在64位有符号整数中的最大值(由INT_64_MAX或类似值表示)为9223372036854775807。
该值从无符号到有符号的转换在n3797 S4.7 / 3的标准中有所涵盖:
如果目标类型已签名,则该值如果可以在目标类型(和位字段宽度)中表示,则不会更改;否则,该值是实现定义的。
由于无法如此表示,因此行为是实现定义的。
在大多数实现中实际发生的是比特值将保持不变。现在val1的值超出了允许的范围,任何使用它都会导致未定义的行为。
特别是两个有符号整数之间的比较,其中一个在允许范围之外,无法可靠地预测。它可能会遵循底层机器硬件中的特定指令,因此您必须检查生成的代码以确定它将是什么。我可以编写代码并告诉你我发现了什么,但是对于不同的编译器或不同的处理器,它可能会有所不同。
如果可能,最好的建议是始终避免未定义的行为。
答案 2 :(得分:1)
比较运算符照常工作:在这种情况下,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;
}
输出(ideone):
val1: -9223372036854775808
val2: 2022435311251187319
Val2 is greater than val1
答案 3 :(得分:1)
在其他方面,我希望你的意思是大于或等于。
Opertor简单地无法工作,因为int64_t意味着存储限制值(-2 ^ 63到2 ^ 63-1)。如果您想要更多范围,请使用未签名版本。对于更多范围,请使用一些现成的bignum库或自己编写一个。 (例如,您可以store large numbers in string并且比较变得非常容易)