问题描述
我通过K&放工作; R Second Edition和想不通,为什么我得到一个确定的结果。我解决问题是计算数据类型的上限和下限。具体做法是:
I'm working through K&R Second Edition, and can't figure out why I'm getting a certain result. The problem I'm solving is calculating upper and lower limits for data types. Specifically:
写一个程序来确定的char,short,int和长变量的范围,包括通过打印从标准头,并直接计算适当的值符号和无符号,哈德如果计算他们:确定的范围各种浮点类型。
我了解位运算符和两个的恭维,并有一个解决方案,我认为应该有符号数据类型的工作,而是它的工作无符号的数据类型而没有任何意义,我。这里的code:
I've learned about bitwise operators and two's compliment, and have a solution I think should work for signed data types, but instead it's working for unsigned data types which doesn't make any sense to me. Here's the code:
#include <stdio.h>
main()
{
signed int i;
i = ~0;
i >>= 1;
printf("Upper limit: %d\n", i);
printf("Lower limit: %d\n", -i -1);
}
这将导致-1被打印为上限,且0打印的下限。但是,如果我改变我对一个unsigned int,我得到的结果,我期待(2147483647和-2147483648)。我不能换我解决这个的头,因为我的理解是,unsigned int可绝不会小于0,和一个符号int应该努力利用这些按位运算符,也就是说,如果它是一个32位系统,
This will result in -1 being printed for the upper limit, and 0 printed for the lower limit. However, if I change i to an unsigned int, I get the result I was expecting (2147483647 and -2147483648). I can't wrap my head around this, because my understanding is that an unsigned int can never be less than 0, and a signed int should work using these bitwise operators, ie, if it's a 32 bit system,
~0 == 11111111111111111111111111111111
和
~0 >> 1 == 011111111111111111111111111111111,
or 2147483647.
任何想法,我要去哪里错了?
Any idea where I'm going wrong?
推荐答案
输出:
-
注意:结果
在EX pressionI&GT;&GT; = 1
,负值右移。 C标准说,这是一个实现定义的操作,以及许多实现定义它是算术移位。在算术移位,最显著位不变(保持MSB(符号位)=1
)。
Note:
"In the expressioni >>= 1
, a negative value is shifted right. The C standard says this is an implementation-defined operation, and many implementations define it to be arithmetic shift. In an arithmetic shift, the most significant bit is unchanged (keeps MSB (signed bit) =1
)".
(你可以阅读:Right用C转向负数的是&GT;方式&gt;
是编译器相关的其是否被烫伤或unsinfed转变,但可能你的情况做了一个算术移位)
(you can read: Right shifting negative numbers in C that >>
is compiler dependent whether its singed or unsinfed shift, but probably in your case its doing an Arithmetic Shift.)
由于这个原因后,code:
For this reason after code:
i = ~0;
i >>= 1;
I
遗体 0〜
。这是二进制== 11111111111111111111111111111111
。
i
remains ~0
. that is in binary == 11111111111111111111111111111111
.
而因为 0〜
== 11111111111111111111111111111111
是== 2'C 补1
是 1
。
And because ~0
== 11111111111111111111111111111111
is == 2'c complement of 1
that is -1
.
所以,当你用打印格式字符串%d个
其打印 1
。您应该使用%U
打印最大的无符号数是== 0〜
。
So when you prints with format string %d
it print -1
. You should use %u
to print max unsigned value that is == ~0
.
重要,这里要注意:
§6.2.6.2语言45 ,©ISO / IEC ISO / IEC 9899:201X
(一补数)。其中哪些是适用
实施德网络定义
,因为无论是带符号位的值 1
和
所有的价值为零位(对于前两个),或者用符号位和所有价值
第1位(为一补数),是一个陷阱重新presentation还是正常
值。在符号和幅度与一补数,如果的情况下,
这种重presentation是正常值它被称为负零。
(ones’ complement). Which of these applies is implementation-defined
, as is whether the value with sign bit 1
and all value bits zero (for the first two), or with sign bit and all value bits 1 (for ones’ complement), is a trap representation or a normal value. In the case of sign and magnitude and ones’ complement, if this representation is a normal value it is called a negative zero.
您的理解是:
〜0&GT;&GT; 1 == 011111111111111111111111111111111
是错误的! (它可能是,但在你的系统没有发生,根据输出)
~0 >> 1 == 011111111111111111111111111111111
is wrong! (it may be but not happening in your system, according to output)
〜0&GT;&GT; 1 == 111111111111111111111111111111111
,注意MSB(签位) 1
。
~0 >> 1 == 111111111111111111111111111111111
, note MSB(signed bit) is 1
.
有关无符号的转变,尝试以下操作:
For unsigned shift, try following:
〜0U&GT;&GT; 1 == 011111111111111111111111111111111
注意后缀的 U
作为无符号。
Notice Suffix U
for unsigned.
第二个printf :结果
因为 I
是 1
,所以在第二个前pression -i - 1
== - (-1) - 1
== 1 - 1
== 0
所以输出为零: 0
Second printf:
Because i
is -1
, So in second expression -i - 1
== - (-1) - 1
== 1 - 1
== 0
so output is zero : 0
.
这篇关于计算数据类型的范围用C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!