一元减去0x80000000(有符号和无符号) [英] unary minus for 0x80000000 (signed and unsigned)

查看:583
本文介绍了一元减去0x80000000(有符号和无符号)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

n3337.pdf草案5.3.1.8说明:

The n3337.pdf draft, 5.3.1.8, states that:


一元的操作数 运算符应具有算术或无范围枚举类型,结果为其操作数的否定。对积分或枚举操作数执行积分提升。无符号数量的负数通过从2ⁿ减去其值来计算,其中n是提升的操作数中的位数。结果的类型是提升的操作数的类型。

The operand of the unary - operator shall have arithmetic or unscoped enumeration type and the result is the negation of its operand. Integral promotion is performed on integral or enumeration operands. The negative of an unsigned quantity is computed by subtracting its value from 2ⁿ, where n is the number of bits in the promoted operand. The type of the result is the type of the promoted operand.

对于某些情况,这是足够的。假设unsigned int是32位宽,那么( - (0x80000000u))== 0x80000000u ,不是吗?

For some cases it is enough. Suppose unsigned int is 32 bits wide, then (-(0x80000000u)) == 0x80000000u, isn't it?

仍然,我没有找到任何关于unary减去无符号0x80000000。此外,C99标准草案n1336.pdf,6.5.3.3似乎没有说到:

Still, I can not find anything about unary minus on unsigned 0x80000000. Also, C99 standard draft n1336.pdf, 6.5.3.3 seems to say nothing about it:


一元运算符的结果是它的(促进)操作数的负数。

The result of the unary - operator is the negative of its (promoted) operand. The integer promotions are performed on the operand, and the result has the promoted type.

UPDATE2:让我们假设unsigned int是32位宽。所以,问题是:在C(有符号和无符号)中的一元减号和C ++中的一元减号(仅限有符号)?

UPDATE2: Let us suppose that unsigned int is 32 bits wide. So, the question is: what about unary minus in C (signed and unsigned), and unary minus in C++ (signed only)?

UPDATE1:和编译时行为(即常量折叠)很有趣。

UPDATE1: both run-time behavior and compile-time behavior (i.e. constant-folding) are interesting.

(相关:为什么是abs(0x80000000)== 0x80000000?

推荐答案

问题,您包含的报价的重要部分是:

For your question, the important part of the quote you've included is this:


无符号数的负数通过减去
value from2ⁿ,其中n是提升的操作数中的位数。

The negative of an unsigned quantity is computed by subtracting its value from 2ⁿ, where n is the number of bits in the promoted operand.

因此,要知道 -0x80000000u 是,我们需要知道 n ,类型中的位数 0x80000000u 。这是至少32,但这是我们所知(没有关于实现中的类型的大小的进一步信息)。给定 n 的一些值,我们可以计算出结果:

So, to know what the value of -0x80000000u is, we need to know n, the number of bits in the type of 0x80000000u. This is at least 32, but this is all we know (without further information about the sizes of types in your implementation). Given some values of n, we can calculate what the result will be:

n   | -0x80000000u 
----+--------------
32  | 0x80000000
33  | 0x180000000
34  | 0x380000000
48  | 0xFFFF80000000
64  | 0xFFFFFFFF80000000

(例如, unsigned int 为16位, unsigned long 为64位时将具有64的 n )。

(For example, an implementation where unsigned int is 16 bits and unsigned long is 64 bits would have an n of 64).

C99在§6.2.5中隐藏了相同的措辞。类型p9:

C99 has equivalent wording hidden away in §6.2.5 Types p9:


涉及无符号操作数的计算永远不会溢出,因为
a结果不能由结果无符号整数表示
类型以大于最大$ b的数字模数

A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

一元的结果 -

The result of the unary - operator on an unsigned operand other than zero will always be caught by this rule.

使用32位 int $ c>, 0x80000000 的类型将是 unsigned int ,无论是否缺少 u 后缀,所以结果仍然是 0x80000000 ,类型为 unsigned int

With a 32 bit int, the type of 0x80000000 will be unsigned int, regardless of the lack of a u suffix, so the result will still be the value 0x80000000 with type unsigned int.

如果使用小数常数 2147483648 ,它将具有类型 long ,并且计算将被签名。结果将是类型为 long 的值 -2147483648

If instead you use the decimal constant 2147483648, it will have type long and the calculation will be signed. The result will be the value -2147483648 with type long.

这篇关于一元减去0x80000000(有符号和无符号)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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