gpt4 book ai didi

c++ - 为什么 long l = 0x80000000 是正数?

转载 作者:行者123 更新时间:2023-12-01 14:47:46 26 4
gpt4 key购买 nike

在 C++ 中,为什么 long l = 0x80000000; 是正数?

C++:
long l = 0x80000000; // l is positive. Why??

int i = 0x80000000;
long l = i; // l is negative

根据本网站:https://en.cppreference.com/w/cpp/language/integer_literal , 0x80000000 应该是一个带符号的整数,但它似乎不是大小写,因为当它被分配给 l 时,符号扩展不会发生。

Java:
long l = 0x80000000; // l is negative

int i = 0x80000000;
long l = i; // l is negative

另一方面,Java 具有更一致的行为。

C++ 测试代码:

#include <stdio.h>
#include <string.h>

void print_sign(long l) {
if (l < 0) {
printf("Negative\n");
} else if (l > 0) {
printf("Positive\n");
} else {
printf("Zero\n");
}
}

int main() {
long l = -0x80000000;
print_sign(l); // Positive

long l2 = 0x80000000;
print_sign(l2); // Positive

int i = 0x80000000;
long l3 = i;
print_sign(l3); // Negative

int i2 = -0x80000000;
long l4 = i2;
print_sign(l4); // Negative
}

最佳答案

从您的链接:“整数文字的类型是值可以适合的第一种类型,来自类型列表,这取决于使用了哪个数字基数和哪个整数后缀。”对于十六进制值列表 int、unsigned int...

您的编译器使用 32 位整数,因此最大(有符号)整数为 0x7FFFFFFF。 signed int 不能表示 0x8000000...0xFFFFFFF 的原因是它需要 32 位的 2^32 个可能值中的一些来表示负数。但是,0x80000000 适合 32 位无符号整数。您的编译器使用 64 位 long,最多可以容纳 0x7FFF FFFF FFFF FFFF,因此 0x80000000 也适合有符号的 long,因此 long l 是正值 0x80000000。

另一方面,int i 是一个带符号的 int,根本不适合 0x80000000,因此会出现未定义的行为。当有符号数太大而不适合 C++ 时,经常发生的事情是使用二元补码运算,并且数字回绕到一个大的负数。 (不要依赖这种行为;已知优化会打破这种行为)。无论如何,在这种情况下似乎确实发生了补码行为,导致 i 为负数。

在您的示例代码中,您同时使用了 0x80000000 和 -0x80000000,并且在每种情况下它们都具有相同的结果。其实都是一样的。回想一下 0x8000000 是一个无符号整数。 2003 C++ 标准在 5.3.1c7 中说:“无符号数的负数是通过从 2^n 中减去它的值来计算的,其中 n 是提升的操作数中的位数。” 0x80000000 正好是 2^31,所以 -0x80000000 是 2^32-2^31=2^31。为了获得预期的行为,我们必须改用 -(long)0x80000000。

关于c++ - 为什么 long l = 0x80000000 是正数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61948687/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com