为什么 -(-2147483648) = - 2147483648 在 32 位机器中? [英] Why is -(-2147483648) = - 2147483648 in a 32-bit machine?

查看:24
本文介绍了为什么 -(-2147483648) = - 2147483648 在 32 位机器中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这个问题是不言自明的,我想它可能与溢出有关,但我仍然不太明白.引擎盖下按位发生了什么?

为什么 -(-2147483648) = -2147483648(至少在用 C 编译时)?

解决方案

否定一个(无后缀的)整数常量:

表达式 -(-2147483648) 在 C 中是完美定义的,但是为什么会这样可能并不明显.

当您编写 -2147483648 时,它形成为应用于整数常量的一元减运算符.如果2147483648不能表示为int,则表示为longlong long*(以先适合者为准),C 标准保证后一种类型涵盖该值.

要确认这一点,您可以通过以下方式进行检查:

printf("%zu\n", sizeof(-2147483648));

在我的机器上产生 8.

下一步是应用第二个 - 运算符,在这种情况下,最终值是 2147483648L(假设它最终表示为 long>).如果尝试将其分配给 int 对象,如下所示:

int n = -(-2147483648);

那么实际行为是实现定义的.参考标准:

<块引用>

C11 §6.3.1.3/3 有符号和无符号整数

否则,新类型是有符号的,无法表示值在里面;结果要么是实现定义的,要么是一个引发了实现定义的信号.

最常见的方法是简单地切断较高的位.例如,GCC 文档如下:

<块引用>

为了转换为宽度 N 的类型,该值以 2^N 为模减少在类型范围内;没有发出信号.

从概念上讲,转换为宽度 32 的类型可以通过按位与操作来说明:

值 &(2^32 - 1)//保留 32 个最低有效位

根据二进制补码算法,n的值code>由全零和MSB(符号)位组成,代表-2^31的值,即-2147483648.

否定 int 对象:

如果你试图否定 int 对象,它持有 -2147483648 的值,那么假设二进制补码机,程序将表现出未定义行为:

n = -n;//UB if n == INT_MIN 和 INT_MAX == 2147483647

<块引用>

C11 §6.5/5 表达式

如果异常情况在评估一个表达式(即,如果结果未在数学上定义或不在其类型的可表示值范围内),行为未定义.

其他参考资料:

<小时>

*) 在被撤销的C90标准中,没有long long类型,规则不同.具体来说,无后缀十进制的序列是intlong intunsigned long int(C90 §6.1.3.2 Integer constants).

†) 这是由于 LLONG_MAX,必须至少为 +9223372036854775807(C11 §5.2.4.2.1/1).

I think the question is self explanatory, I guess it probably has something to do with overflow but still I do not quite get it. What is happening, bitwise, under the hood?

Why does -(-2147483648) = -2147483648 (at least while compiling in C)?

解决方案

Negating an (unsuffixed) integer constant:

The expression -(-2147483648) is perfectly defined in C, however it may be not obvious why it is this way.

When you write -2147483648, it is formed as unary minus operator applied to integer constant. If 2147483648 can't be expressed as int, then it s is represented as long or long long* (whichever fits first), where the latter type is guaranteed by the C Standard to cover that value.

To confirm that, you could examine it by:

printf("%zu\n", sizeof(-2147483648));

which yields 8 on my machine.

The next step is to apply second - operator, in which case the final value is 2147483648L (assuming that it was eventually represented as long). If you try to assign it to int object, as follows:

int n = -(-2147483648);

then the actual behavior is implementation-defined. Referring to the Standard:

C11 §6.3.1.3/3 Signed and unsigned integers

Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

The most common way is to simply cut-off the higher bits. For instance, GCC documents it as:

For conversion to a type of width N, the value is reduced modulo 2^N to be within range of the type; no signal is raised.

Conceptually, the conversion to type of width 32 can be illustrated by bitwise AND operation:

value & (2^32 - 1) // preserve 32 least significant bits

In accordance with two's complement arithmetic, the value of n is formed with all zeros and MSB (sign) bit set, which represents value of -2^31, that is -2147483648.

Negating an int object:

If you try to negate int object, that holds value of -2147483648, then assuming two's complement machine, the program will exhibit undefined behavior:

n = -n; // UB if n == INT_MIN and INT_MAX == 2147483647

C11 §6.5/5 Expressions

If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.

Additional references:


*) In withdrawed C90 Standard, there was no long long type and the rules were different. Specifically, sequence for unsuffixed decimal was int, long int, unsigned long int (C90 §6.1.3.2 Integer constants).

†) This is due to LLONG_MAX, which must be at least +9223372036854775807 (C11 §5.2.4.2.1/1).

这篇关于为什么 -(-2147483648) = - 2147483648 在 32 位机器中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆