常量 32768 和 0x8000 之间的类型差异会产生影响吗?

发布于 2024-12-14 07:30:44 字数 212 浏览 0 评论 0原文

该标准指定像 0x8000(大于有符号整数的大小)这样的十六进制常量是无符号的(就像八进制常量一样),而像 32768 这样的十进制常量是有符号长整型。 (确切的类型假定为 16 位整数和 32 位长。)但是,在常规 C 环境中,两者将具有相同的表示形式,即二进制 1000 0000 0000 0000。 这种差异是否真的会产生不同的结果?换句话说,这种差异是否有可能产生重大影响?

The Standard specifies that hexadecimal constants like 0x8000 (larger than fits in a signed integer) are unsigned (just like octal constants), whereas decimal constants like 32768 are signed long. (The exact types assume a 16-bit integer and a 32-bit long.) However, in regular C environments both will have the same representation, in binary 1000 0000 0000 0000.
Is a situation possible where this difference really produces a different outcome? In other words, is a situation possible where this difference matters at all?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

天气好吗我好吗 2024-12-21 07:30:44

是的,这可能很重要。如果您的处理器具有 16 位 int 和 32 位 long 类型,则 32768 具有 long 类型(因为 32767 是最大正数)适合有符号 16 位 int 的值),而 0x8000(因为它也被视为 unsigned int)仍然适合 16 位无符号整数

现在考虑以下程序:

int main(int argc, char *argv[])
{
  volatile long long_dec = ((long)~32768);
  volatile long long_hex = ((long)~0x8000);

  return 0;
}

当 32768 被认为是long时,求反将反转 32 位,
产生 long 类型的表示形式 0xFFFF7FFF;演员阵容是
多余。
当 0x8000 被认为是 unsigned int 时,否定将反转
16 位,表示为 unsigned int 类型的 0x7FFF;
然后,转换将零扩展到 long 值 0x00007FFF。
参见 H&S5,第 2.7.1 节,第 24 页。

最好根据需要使用 UULL 来扩充常量。

Yes, it can matter. If your processor has a 16-bit int and a 32-bit long type, 32768 has the type long (since 32767 is the largest positive value fitting in a signed 16-bit int), whereas 0x8000 (since it is also considered for unsigned int) still fits in a 16-bit unsigned int.

Now consider the following program:

int main(int argc, char *argv[])
{
  volatile long long_dec = ((long)~32768);
  volatile long long_hex = ((long)~0x8000);

  return 0;
}

When 32768 is considered long, the negation will invert 32 bits,
resulting in a representation 0xFFFF7FFF with type long; the cast is
superfluous.
When 0x8000 is considered unsigned int, the negation will invert
16 bits, resulting in a representation 0x7FFF with type unsigned int;
the cast will then zero-extend to a long value of 0x00007FFF.
Look at H&S5, section 2.7.1 page 24ff.

It is best to augment the constants with U, UL or L as appropriate.

吃不饱 2024-12-21 07:30:44

在具有 64 位 long 的 32 位平台上,以下代码中的 ab 将具有不同的值:

int x = 2;
long a = x * 0x80000000; /* multiplication done in unsigned -> 0           */
long b = x * 2147483648; /* multiplication done in long     -> 0x100000000 */

On a 32 bit platform with 64 bit long, a and b in the following code will have different values:

int x = 2;
long a = x * 0x80000000; /* multiplication done in unsigned -> 0           */
long b = x * 2147483648; /* multiplication done in long     -> 0x100000000 */
新雨望断虹 2024-12-21 07:30:44

另一项尚未给出的检查:将 -1 与 32768 和 0x8000 进行比较(使用大于或小于运算符)。或者,就此而言,尝试将它们与等于 -32768 的“int”变量进行比较。

Another examine not yet given: compare (with greater-than or less-than operators) -1 to both 32768 and to 0x8000. Or, for that matter, try comparing each of them for equality with an 'int' variable equal to -32768.

泪冰清 2024-12-21 07:30:44

假设 int 是 16 位,long 是 32 位(这实际上相当不寻常;int 更常见的是 32 位):

printf("%ld\n", 32768);  // prints "32768"
printf("%ld\n", 0x8000); // has undefined behavior

在大多数情况下在上下文中,数值表达式将隐式转换为由上下文确定的适当类型。 (但这并不总是您想要的类型。)这不适用于可变参数函数的非固定参数,例如格式字符串后面的 *printf() 函数之一的任何参数。

Assuming int is 16 bits and long is 32 bits (which is actually fairly unusual these days; int is more commonly 32 bits):

printf("%ld\n", 32768);  // prints "32768"
printf("%ld\n", 0x8000); // has undefined behavior

In most contexts, a numeric expression will be implicitly converted to an appropriate type determined by the context. (That's not always the type you want, though.) This doesn't apply to non-fixed arguments to variadic functions, such as any argument to one of the *printf() functions following the format string.

你与昨日 2024-12-21 07:30:44

区别在于,如果您尝试向 16 位 int 添加一个值,它将无法这样做,因为它将超出变量的范围,而如果您使用 32 位长,您可以添加任何数字小于 2^16 。

The difference would be if you were to try and add a value to the 16 bit int it would not be able to do so because it would exceed the bounds of the variable whereas if you were using a 32bit long you could add any number that is less than 2^16 to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文