是什么〜0的C中的价值? [英] what is the value of ~0 in C?

查看:82
本文介绍了是什么〜0的C中的价值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要得到的值 INT_MIN INT_MAX ,我尝试了 〜0 〜0>> 1 ,因为最左边位为符号位。我把他们都 1

这是这么糊涂了,为什么不〜0 原来是为0xffffffff 〜 0 GT;> 1 为0x7FFFFFFF


解决方案

使用:

 〜0U>> 1

后缀'U'未签名的转变行为。


  

等等,混淆起来,为什么不 0〜原来是为0xffffffff


看,是什么 0 说,在四个字节重新presentation:

 位数31 0
               ▼▼
比特数0000 0000 0000 0000 0000 0000 0000 0000
               ▲▲
              MSB LSBLSB - 最低有效位(编号0)
MSB - 最高有效位(编号31)

现在是按位运营商不那么翻转所有位 0 为:

 位数31 0
               ▼▼
数位1111 1111 1111 1111 1111 1111 1111 1111
               ▲▲
              MSB LSB

由于MSB的= 1 这个重新presentation被视为负数,其大小被发现使用2'complement数学是 -1

如何?

什么是 1 ?它是:

 数位0000 0000 0000 0000 0000 0000 0000 0001
               ▲▲
              MSB LSB

1的 1

 数位1111 1111 1111 1111 1111 1111 1111 1110
               ▲▲
              MSB LSB

2'complement?在一个人的补充添加 1 ,那就是:

 数位1111 1111 1111 1111 1111 1111 1111 1111
               ▲▲
              MSB LSB

这同样的,当你获得为0〜?这就是为什么你得到 1 输出。

现在>>移位运算符?

在大多数实现C >>操作者被定义为一个算术右移,其中preserves符号位MSB。因此,〜0>> 1 是指出,但 1 保持不变。


  

6.5.7 [按位移位运算符]


  
  

5 E1&GT的结果;> E2 E1 右移 E2 位的位置。如果 E1 有一个无符号的类型,或者 E1 有符号类型和非负值,则结果的值 E1 / 2E2 的商的组成部分。如果 E1 有签署类型和负值,结果值是实现定义的。


您的要求就是所谓的无符号的右移>> 键,您可以根据需要使用。这就是为什么我为后缀的无符号数是发现行为 U 0 U

如何打印INT_MIN和INT_MAX?

由于打印INT_MIN和INT_MAX是有点棘手(因为设置MSB和位溢出的不确定和实施的行为)用C,所以我写了一个code如下:

 的#include<&stdio.h中GT;
#包括LT&;&limits.h中GT; / *包括CHAR_BIT * /
诠释主(){
  INT my_int_min = 1U<< ((的sizeof(int)的* CHAR_BIT) - 1);
  INT my_int_max =〜0U>> 1;
  的printf(INT_MIN =%d个\\ N,my_int_min);
  的printf(INT_MAX =%d个\\ N,my_int_max);
  返回0;
}

看到它执行@ codePAD 时,它的输出是:

  INT_MIN = -2147483648
INT_MAX = 2147483647

这是如何code的工作?

请注意32位数字的范围是 [ - 2147483648,2147483647] 这是等同于 [ - 2 31 2 31 -1]

INT_MIN: -2 31 == -2147483648是:

  1000 0000 0000 0000 0000 0000 0000 0000
    ▲▲
    MSB LSB

在EX pression 1U<< ((的sizeof(int)的* CHAR_BIT) - 1),我班第一位的LSB(即1)在MSB最左侧,而由于C,设置签位是不确定的行为当操作数烧焦类型的,所以我用无符号一1U。


  

6.5.7 [按位移位运算符]


  
  

E1 1所述的结果;< E2 是E1左移E2位位置;腾空位用零填充。如果E1有一个无符号类型,则结果的值是E1×2E2,减小模数比在结果类型的最大值重新presentable一个。 如果E1有符号类型和非负价值,E1×2E2是结果型重presentable,然后就是得到的值;否则,行为是不确定的。


另外要注意的一点是我用CHAR_BIT,在C实现讲述了一个字符位数limits.h中定义的标准宏(记住:一个char始终是一个字节大小,但在一个字节的位数可以不同系统上的不同并不总是保证是8)。

INT_MAX: 2 31 -1 == 2147483647

  0111 1111 1111 1111 11111111 11111111
    ▲▲
    MSB LSB

I want to get the value INT_MIN and INT_MAX, and I've tried ~0 and ~0 >> 1 since the leftmost bit is a sign bit. I got them both -1.

It's so confused that why not ~0 turns out to be 0xffffffff and ~0 >> 1 to be 0x7fffffff?

解决方案

Use:

~0U >> 1

Suffix 'U' for unsigned shift behavior.

so, confused that why not ~0 turns out to be 0xffffffff?

See, what is 0 say in four bytes representation:

BIT NUMBER    31                                     0
               ▼                                     ▼
number bits    0000 0000 0000 0000 0000 0000 0000 0000 
               ▲                                     ▲ 
              MSB                                   LSB



LSB - Least Significant Bit (numbered 0)
MSB - Most  Significant Bit (numbered 31) 

Now ~ is bitwise not operator then flips all bits in 0 as:

BIT NUMBER    31                                     0
               ▼                                     ▼
number bits    1111 1111 1111 1111 1111 1111 1111 1111
               ▲                                     ▲ 
              MSB                                   LSB

Because of MSB = 1 this representation is treated as negative number and its magnitude is find using 2'complement math that is -1.

How?

What is 1 ? it is:

number bits    0000 0000 0000 0000 0000 0000 0000 0001 
               ▲                                     ▲ 
              MSB                                   LSB

1's complement of 1

number bits    1111 1111 1111 1111 1111 1111 1111 1110
               ▲                                     ▲ 
              MSB                                   LSB

2'complement? Add 1 in one's complement, that is:

number bits    1111 1111 1111 1111 1111 1111 1111 1111
               ▲                                     ▲ 
              MSB                                   LSB

this same as when you gets ~0 ? that is why you are getting -1 output.

Now >> shift operator?

In most implementation of C >> operator is defined as an arithmetic right shift, which preserves the sign bit MSB. So ~0 >> 1 is noting but -1 remains same.

6.5.7 [Bitwise shift operators]

5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

You requirement is what is called unsigned right shift >> and the behavior you needed can be find using unsigned number that is why I suffixed U as 0U.

How to print INT_MIN and INT_MAX?

Because printing INT_MIN and INT_MAX is bit tricky(because of undefined and implementation behavior of setting MSB and bit-overflow) in C so I have written a code as follows:

#include <stdio.h>
#include<limits.h> /* include for CHAR_BIT */
int main(){
  int my_int_min = 1U << ((sizeof(int) * CHAR_BIT) - 1);
  int my_int_max = ~0U >> 1;
  printf("INT_MIN  = %d\n", my_int_min);
  printf("INT_MAX  = %d\n", my_int_max);
  return 0;
}

See it executing @codepad, it output is:

INT_MIN  = -2147483648
INT_MAX  = 2147483647 

How does this code work?

Note for 32-bit number range is [-2147483648, 2147483647] that is equals to [-231, 231 -1 ].

INT_MIN: -231 == -2147483648 is:

    1000 0000 0000 0000 0000 0000 0000 0000 
    ▲                                     ▲ 
    MSB                                   LSB

In expression 1U << ((sizeof(int) * CHAR_BIT) - 1), I shifts first bit the LSB(that is 1) to left most side at MSB, And because in C, setting signed bit is undefined behavior when operand is singed type so I used unsigned one 1U.

6.5.7 [Bitwise shift operators]

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2 , reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

Another point to note is I used CHAR_BIT a standard macro defined in limits.h that tells number of bits in one char in a C implementation (remember: A char is always one byte size but number of bits in one bytes can be different on different system not always guaranteed to be 8).

INT_MAX: 231 -1 == 2147483647

    0111 1111 1111 1111 1111 1111 1111 1111
    ▲                                     ▲ 
    MSB                                   LSB

这篇关于是什么〜0的C中的价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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