简体   繁体   English

C语言编程。 无符号整数评估问题

[英]C programming. Issue with unsigned integer evaluation

In C programming I have this problem : 在C编程中,我有这个问题:

int v = 0XFFFD;
unsigned z=1;

Evaluate the expressions: 评估表达式:

a) (v+1)/2  
b) -1 > z

In the problem book, for 在问题书中,
a) the answer is -1 , and for a)答案是-1 ,对于
b) the answer is 1 . b)答案是1

Can anybody explain why? 有人可以解释为什么吗?
Because in my opinion for 因为我认为
a) I think the answer is 32767 , and for a)我认为答案是32767 ,对于
b) is 0 . b)是0

Case 1 : By default type of int is signed that means compile will check sign bit and if sign bit is one means output will be negative. 情况1:默认情况下,int类型是带符号的,这意味着编译将检查符号位,如果符号位为1,则输出将为负。

int v = 0XFFFD

How v will be stored in memory,if its a little endian it looks like below v将如何存储在内存中,如果它有一个小端,则如下所示

    -------------------------
    | 1111 1111  | 1111 1101 |
    -------------------------
   MSB                      LSB
                             v

As you can see sign bit(15th bit, in case of short int) is one, and negative number are stored in memory as two's compliment. 如您所见,符号位(第15位,如果为int短整数)为1,并且负数作为二进制补码存储在内存中。 and two's compliment of v i is v i的二的补充是

 one's compliment =>  0000 0000 |  0000 0010
                                          +1
                      -----------------------
                      0000 0000 |  0000 0011 => 3 and since sign bit is one  that's why v is -3 

When you are doing (v+1)/2 == (-3+1)/2 => -1 当您在做(v+1)/2 == (-3+1)/2 => -1

Case 2 : 情况2:

unsigned z = 1;

Let's say statement looks like 假设声明看起来像

printf("%d\n", -1 > z);

Here while performing any operation between two operands you should be aware of consequences of if operands types are different. 在这里,当在两个操作数之间执行任何操作时,您应该注意操作数类型不同的后果。

 -1  >  z
 |      |           => comparing different operands
signed unsigned       (one is signed and other one unsigned) => Implicit type conversion will happen i.e implicitly signed gets promoted into unsigned by compiler)
                            ||
                        65535 > 1 => true => pints 1 
                        |
               (-1 is signed and its converted into unsigned and unsigned equivalent of -1 is 65535 in case of shot integer)

C defines its integer math operation functionally, not as bit patterns. C在功能上定义了其整数数学运算,而不是位模式。 Thinking of a number in bits may be useful, but let us see what C specifies. 以位为单位的数字思考可能会有用,但是让我们看看C所指定的内容。


int v = 0XFFFD;

int must be at least encode [-32767 ... 32767]. int必须至少编码[-32767 ... 32767]。 OP's case appears to use minimally sized int . OP的案例似乎使用了最小尺寸的int

0XFFFD is a hexadecimal constant with the value of 65,533. 0XFFFD十六进制常数 ,值为65,533。 Its type is the first that it fits in: int, unsigned, long, unsigned long ... . 它的类型是它适合的第一个类型: int, unsigned, long, unsigned long ... In this case it is unsigned . 在这种情况下,它是unsigned

int v = some_unsigned requires a conversion of the unsigned to int . int v = some_unsigned需要将unsigned转换为int When the source is out-of-range of an int , it is implementation defined what happens. 当源超出int范围时, int 实现定义发生的事情。 A common result is a "wrap-around" by subtracting 2 16 . 常见的结果是减去2 16得到“环绕”。 Code could instead assign INT_MAX . 代码可以改为分配INT_MAX It is implementation defined . 它是实现定义的 Apparently code is wrapping in OP's case. 显然,在OP的情况下包装了代码。

int v = 65533 - 65536; // -3
// or maybe
int v = 32767; // Uncommon implementation defined result.

(v+1)/2 is simply then (-3 + 1)/2 --> -1. (v+1)/2就是(-3 + 1)/2 > -1。

Had the hexadecimal constant fit in an int , perhaps on a platform with a 32-bit int , (65533 + 1)/2 would have been 32767 as considered by OP. 如果十六进制常量适合int ,也许在具有32位int的平台上,则OP认为(65533 + 1)/2为32767。


unsigned z = 1; is simple. 很简单。 z has the value of 1. z的值为1。

-1 > z compares an int -1 to an unsigned . -1 > z比较int -1unsigned Compares are done with the same type. 比较是使用相同的类型完成的。

unsigned is higher rank than int , so -1 is converted to an unsigned and its value is changed by adding UINT_MAX +1 . unsigned等级更高int ,所以-1被转换为一个unsigned ,它的值是通过将改变UINT_MAX +1 -1 + UINT_MAX +1 --> UINT_MAX . -1 + UINT_MAX +1 > UINT_MAX

Now the compare is like UINT_MAX > 1 which is true. 现在比较就像UINT_MAX > 1一样。 A compare result is an int , either 0 or 1. The result here is an int 1. 比较结果是int ,可以是0或1。这里的结果是int 1。

The result is independent of the range of unsigned . 结果与unsigned的范围无关。

  1. because int is signed integer, 0xfffd equals -3. 因为int是有符号整数,所以0xfffd等于-3。 So (v+1)/2 gets -1 所以(v+1)/2得到-1
  2. signed integer is automatically converted (coercion) to unsigned integer if you compare signed integer with unsigned integer. 如果将带符号整数与无符号整数进行比较,则带符号整数将自动转换(强制)为无符号整数。

Short story : your book seems to be quite bad. 简短的故事 :您的书似乎很糟糕。

Never, ever, initialize an int (a signed type) with a value that can be unsigned such as a hexadecimal constant. 永远不要用一个可以为无符号的值(例如十六进制常量)初始化一个int (一个有符号的类型)。

Long story : 长话

The results of "1." 结果为“ 1”。 depends on a lot of things. 取决于很多事情。 First, it would be important to know the number of significant bits of int . 首先,重要的是要知道int的有效位数。 In the following let us assume that it is 16 bit, otherwise the questions is even more senseless. 在下面,让我们假设它是16位,否则问题将变得更加毫无意义。

If it is 16, then the hex constant on the right side is greater than the maximal int . 如果为16,则右侧的十六进制常数大于最大int Since integer constants in C always are positive, it doesn't fit into an int and thus it has type unsigned int . 由于C中的整数常量始终为正,因此它不适合int ,因此类型为unsigned int

Thus a conversion of an unsigned to int must be done for the intialization. 因此,必须将unsigned转换为int才能进行初始化。 This is "implementation defined" that is your compiler is allowed to do what pleases, as long as it is documented. 这是“实现定义的”,即只要有文档记录,编译器就可以做自己喜欢的事情。

Many compilers do a "lazy" conversion, that is, they just chose the value that has the same representation as the unsigned value. 许多编译器执行“惰性”转换,也就是说,他们只是选择了与unsigned值具有相同表示形式的值。 If your machine has two's representation for int (again an implementation dependent choice) the result would be a negative value, most likely -3 . 如果您的机器具有int 2表示形式(再次取决于实现的选择),则结果将为负值,最有可能为-3

So, the real answer for "1." 因此,真正的答案是“ 1”。 is: it depends . 是: 这取决于 An introductory book should never ask a question in that way, simply suggesting that the result of that operation is depending on the integer representation. 入门书籍绝对不要以这种方式提出问题,只是建议该操作的结果取决于整数表示形式。 Integer representation only comes in by accident. 整数表示只是偶然出现的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM