一元运算符“-”代表什么在C / C ++(和不同的编译器)中对无符号数据类型做什么? [英] What does the unary operator "-" do on unsigned data types in C/C++ (and on different compilers)?

查看:166
本文介绍了一元运算符“-”代表什么在C / C ++(和不同的编译器)中对无符号数据类型做什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如:

unsigned int numA = 66; // or anything really
unsigned int numB = -numA;
unsigned int numC = numA & numB

我了解按位补码运算符可用于获取两者的补码(与+1)。

I understand that the bitwise complement operator can be used to get the two's complement (in conjunction with a +1).

我问的原因是因为我在国际象棋引擎的某些代码中偶然发现了这一点。国际象棋引擎会做很多棘手的事情来获得绝对速度,特别是在每秒产生数百万次的移动生成功能中。 (这并不是魔术位板移动生成的一个示例,这是其中最优化的示例)。特别是这种象棋引擎代码只能在gcc编译下正常工作(我怀疑)。

The reason I ask is because I stumbled upon this in some code for a chess engine. Chess engines do a lot of 'hacky' things to get absolute speed, especially in the move generation functions that are called millions of times per second. (It doesn't help that it was an example of magic bitboard move generation - the most optimized of them all). This chess engine code in particular only works correctly under gcc compilation (I suspect).

不同的编译器如何处理?特别是,与VS Studio 2012 Express中的C ++编译器相比,gcc如何处理此问题。

How do different compilers treat this? In particular, how does gcc handle this compared to the C++ compiler in VS Studio 2012 Express.

谢谢。

推荐答案

标准中的相关报价实际上是这样的:

The relevant quote from the Standard is actually this:


(§5.3.1/ 8 )一元运算符的操作数应具有算术或无作用域的枚举类型,其结果是其操作数的取反。积分提升是对积分或枚举操作数执行的。通过从2 n 中减去无符号数量的负值来计算负数量,其中n是提升操作数中的位数。结果的类型就是提升后的操作数的类型。

(§5.3.1/8) 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 2n, where n is the number of bits in the promoted operand. The type of the result is the type of the promoted operand.

(来自C ++ 11;它以前是5.3 .1 / 7(在较早的版本中)。

(This is from C++11; it used to be 5.3.1/7 in older versions.)

因此, -num 将被评估为2 CHAR_BIT * sizeof(num)-num (‡)。结果将是与操作数相同的类型(在整数提升之后),即也将是无符号的。

So -num will be evaluated as 2CHAR_BIT*sizeof(num) - num (‡). The result will be of the same type as the operand (after integer promotion), i.e. it will also be unsigned.

我刚刚在GCC上进行了测试,它似乎执行了严格按照标准描述的方式进行操作。我将假定Visual C ++也是如此。

I just tested with GCC and it seems to perform the operation in precisely the way described by the Standard. I'll assume this is the case for Visual C++ as well; otherwise it's a bug.

(‡)此公式假定相关的位数对应于内存中变量的大小(以位为单位)。正如基思·汤普森(Keith Thompson)在评论中指出的那样,如果有填充位(即,并非所有位都参与数值表示的情况,根据第3.9.1 / 1节是可能的),则不能成立。在使用比表示数值更多位数存储值的系统上,公式将不准确。 (不过,我个人实际上并不知道任何这样的系统。)

(‡) This formula assumes that the relevant number of bits corresponds to the size (in bits) of the variable in memory. As Keith Thompson points out in the comment, this can't be true if there are padding bits (i.e. when not all bits participate in the representation of the numerical value, which is possible according to §3.9.1/1). On a system that uses more bits to store the value than are used to represent the numerical value, the formula will not be accurate. (I, personally, am not actually aware of any such system, though.)

这篇关于一元运算符“-”代表什么在C / C ++(和不同的编译器)中对无符号数据类型做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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