10

我很难掌握 C 中的数据类型。我正在阅读一本 C 书籍,其中一个挑战是询问 ashort可以存储的最大和最小数字是多少。

使用sizeof(short);我可以看到一个 short 消耗 2 个字节。这意味着它是 16 位,这意味着两个数字,因为存储数字的二进制表示需要 8 位。例如,9 将00111001填满一位。那么无符号的不是0到99,而有符号的不是-9到9吗?

我知道我错了,但我不知道为什么。这里说有符号的最大值是 (-)32,767,无符号的最大值是 65,535。

短整数,2 字节,16 位,-32,768 -> +32,767 范围 (16kb)

4

5 回答 5

18

想一想十进制。如果您只有 2 位数字,这意味着您可以将 from 存储0099其中。如果您有 4 位数字,则该范围0000变为9999

二进制数类似于十进制,除了数字只能是0and 1,而不是0, 1, 2, 3, ..., 9

如果你有这样的号码:

01011101

这是:

0*128 + 1*64 + 0*32 + 1*16 + 1*8 + 1*4 + 0*2 + 1*1 = 93

如您所见,您可以存储比9一个字节更大的值。在一个无符号的 8 位数字中,您实际上可以存储从00000000到 的值11111111,即十进制的 255。

在一个 2 字节的数字中,这个范围变成了从00000000 0000000011111111 11111111恰好是 65535。

您的说法“存储数字的二进制表示需要 8 位”就像说“存储数字的十进制表示需要 8 位”,这是不正确的。例如,数字 12345678901234567890 的位数超过 8 位。同样,您不能将所有数字都放入 8 位,而只能容纳 256 个。这就是你得到 2 字节 ( short)、4 字节 ( int) 和 8 字节 ( long long) 数字的原因。实际上,如果您需要更大范围的数字,则需要使用库。

只要涉及负数,在 2 的补码计算机中,它们只是使用范围的上半部分作为负值的惯例。这意味着1左侧有 a 的数字被认为是负数。

尽管如此,这些数字与它们的正值模 256(模如果位)一致,正如数字所暗示那样2^nn例如,如果无符号数11111111为 255,如果有符号-1数则以 256 为模全等。

于 2012-07-29T17:32:47.810 回答
11

您阅读的参考是正确的。至少,对于通常的 C 实现,其中short16 位 - 这在标准中实际上并没有固定。

16 位可以容纳 2^16 种可能的位模式,即 65536 种可能性。有符号短裤是 -32768 到 32767,无符号短裤是 0 到 65535。

于 2012-07-29T17:30:46.497 回答
9

这在 中定义<limits.h>,并且是SHRT_MIN& SHRT_MAX

于 2012-07-29T17:30:45.653 回答
3

其他人已经为您发布了很好的解决方案,但我认为他们没有遵循您的想法并解释您错在哪里。我会尝试。

我可以看到一个 short 消耗 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。有符号二进制表示的规则在此处进行了很好的描述。

希望能帮助到你!

于 2012-07-29T17:48:07.683 回答
1

找到任何无符号二进制表示数字的范围的公式:

2 ^ (sizeof(type)*8)
于 2012-07-29T17:32:19.267 回答