我很难在C中掌握数据类型。我正在阅读一本C书,其中一个挑战是询问short
可以存储的最大和最小数字。
使用sizeof(short);
我可以看到短消耗2个字节。这意味着它是16位,这意味着两个数字,因为它需要8位来存储数字的二进制表示。例如,9将填充一位00111001
。那么对于无符号,并且-9到9签名,它不会是0到99吗?
我知道我错了,但我不确定为什么。它表示here签名的最大值为( - )32,767,未签名的最大值为65,535。
short int,2 Bytes,16 Bits,-32,768 - > +32,767范围(16kb)
答案 0 :(得分:16)
用十进制思考一秒钟。如果您只有2位数字,则表示您可以将00
存储到99
。如果您有4位数字,则该范围将变为0000
到9999
。
二进制数类似于十进制数,但数字只能是0
和1
,而不是0
,1
,2
,{ {1}},...,3
。
如果你有这样的数字:
9
这是:
01011101
正如您所看到的,您可以在一个字节中存储比0*128 + 1*64 + 0*32 + 1*16 + 1*8 + 1*4 + 0*2 + 1*1 = 93
更大的值。在无符号的8位数字中,您实际上可以存储从9
到00000000
的值,即十进制的255。
在一个2字节的数字中,此范围从11111111
变为00000000 00000000
,恰好是65535.
您的陈述“存储数字的二进制表示需要8位”就像是说“存储数字的十进制表示需要8位数”,这是不正确的。例如,编号12345678901234567890的数字超过8位。同样,您不能将所有数字装入8位,而只能装入其中的256位。这就是为什么你得到2字节(11111111 11111111
),4字节(short
)和8字节(int
)的数字。事实上,如果您需要更高范围的数字,则需要使用库。
只要涉及负数,在二进制补码计算机中,它们只是将范围的较高一半用作负值的惯例。这意味着左侧long long
的数字被视为负数。
然而,这些数字是congruent模256(模1
,如果2^n
位)到它们的正值,正如数字真正建议的那样。例如,如果无符号,则数字n
为255;如果是有符号,则11111111
为全等模数为256。
答案 1 :(得分:7)
这是在<limits.h>
中定义的,是SHRT_MIN
&amp; SHRT_MAX
。
答案 2 :(得分:7)
您阅读的参考文献是正确的。至少,对于short
为16位的常规C实现 - 实际上并没有在标准中修复。
16位可以容纳2 ^ 16种可能的位模式,即65536种可能性。签名短路为-32768至32767,无符号短路为0至65535。
答案 3 :(得分:3)
其他人已经为你发布了很好的解决方案,但我认为他们没有按照你的想法解释你错在哪里。我会试试。
我可以看到短消耗2个字节。这意味着它是16位,
到目前为止,你是正确的(虽然short
不能保证长度为2个字节,但int
不能保证为4 - 标准的唯一保证大小(如果我没记错的话)是char
,应该总是1个字节宽。
表示两个数字,因为它需要8位来存储数字的二进制表示。
从这里你开始漂移了一下。它实际上不需要8位来存储数字。根据数字,可能需要16,32 64或甚至更多位来存储它。将16位分为2是错误的。如果不是CPU实现细节,我们可能有,例如,2位数。在这种情况下,这两个位可以存储如下值:
00 - 0 in decimal
01 - 1 in decimal
10 - 2 in decimal
11 - 3 in decimal
要存储4,我们需要3位。因此该值将“不适合”导致溢出。同样适用于16位数字。例如,假设我们在16位中存储十进制的无符号“255”,二进制表示将是0000000011111111
。当您为该数字加1时,它变为0000000100000000
(十进制为256)。因此,如果您只有8位,它将溢出并变为0,因为最重要的位将被丢弃。
现在,16位内存中的最大无符号数是 - 1111111111111111
,十进制为65535。换句话说,对于无符号数字 - 将所有位设置为1,这将产生最大可能值。
对于带符号的数字,最重要的位代表一个符号 - 0表示正数,1表示负数。对于否定值,最大值为1000000000000000
,在基数10中为-32678。有符号二进制表示的规则已有详细描述here。
希望它有所帮助!
答案 4 :(得分:0)
查找任何无符号二进制范围的公式表示数字:
2 ^ (sizeof(type)*8)