是什么〜0的C中的价值? [英] what is the value of ~0 in 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 LSB1的
补1
数位1111 1111 1111 1111 1111 1111 1111 1110
▲▲
MSB LSB2'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 LSBI want to get the value
INT_MIN
andINT_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 be0xffffffff
and~0 >> 1
to be0x7fffffff
?解决方案Use:
~0U >> 1
Suffix 'U' for unsigned shift behavior.
so, confused that why not
~0
turns out to be0xffffffff
?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 in0
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
isE1
right-shiftedE2
bit positions. IfE1
has an unsigned type or ifE1
has a signed type and a nonnegative value, the value of the result is the integral part of the quotient ofE1 / 2E2
. IfE1
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 suffixedU
as0U
.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屋!