【问题标题】:What are the max and min numbers a short type can store in C?短类型可以在 C 中存储的最大和最小数字是多少?
【发布时间】:2012-07-27 12:30:47
【问题描述】:

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

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

我知道我错了,但我不知道为什么。它说here 签名的最大值为 (-)32,767,未签名的最大值为 65,535。

short int,2 字节,16 位,-32,768 -> +32,767 范围 (16kb)

【问题讨论】:

  • 16 位意味着您有 16 个可以打开和关闭的开关。不同开关模式的总数为2^16,即65536个不同的状态。
  • 只是出于好奇,标准允许的范围是多少?
  • @Antimony 请参阅 Richard J. Ross III 的答案中的链接:{SHRT_MAX} 短类型的最大值。最低可接受值:+32 767
  • 请记住,即使 65536 = 2^16,根据limits.h 最大限制为65535,因为65536 被视为溢出

标签: c memory types short


【解决方案1】:

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

二进制数类似于十进制,只是数字只能是01,而不是0123、...、9 .

如果你有这样的号码:

01011101

这是:

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

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

在一个 2 字节的数字中,此范围从 00000000 00000000 变为 11111111 11111111,恰好是 65535。

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

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

尽管如此,这些数字是 congruent 模 256(模 2^n 如果n 位)到它们的正值,正如数字所暗示的那样。例如,数字 11111111 是 255,如果未签名,-1 如果有符号,则模 256 是全等的。

【讨论】:

  • 好的!谢谢你。我得到了它。我必须考虑“base-2”数字而不是 base-10。现在有道理了。我的理解太离谱了!
  • @Mohamad,没错。它与base-10非常相似。每当你感到困惑时,你可以用这个比喻来更好地理解;)
【解决方案2】:

您阅读的参考资料是正确的。至少,对于 short 为 16 位的常用 C 实现 - 这在标准中实际上并没有固定。

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

【讨论】:

  • 但是存储一个数字需要 8 位,对吧? 16位可以存储2个数字吗?我在这里遗漏了一些东西!
  • @Mohamad 一位足以存储 [0;1] 范围内的数字。两位可以存储4个数字。等等……
  • @Mohamad:8 位仅存储 0-255 范围内的数字。 16 位存储 0-25535 范围内的数字。 32 位(通常是int)可以存储 40 亿。你明白了。都是二的幂。
【解决方案3】:

这是在<limits.h> 中定义的,是SHRT_MINSHRT_MAX

【讨论】:

  • OP 显然在理解二进制数方面存在问题。 this 将如何帮助他理解?
  • @Shahbaz:这不会让他理解,但它确实给了他一些简单的十进制数字。 <limits.h> 在编写可移植程序时也是一个非常有价值的工具,谁知道这是否是问题的核心?这个问题的答案恰到好处地平衡了理论和实用性。
【解决方案4】:

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

我可以看到一个 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。有符号二进制表示的规则在here 中有很好的描述。

希望对你有帮助!

【讨论】:

  • 感谢您的精彩解释。我无法在你和 Shahbaz 之间做出选择,尽管支持我的思路!
  • 不客气!我自己也对这些事情感到困惑 :) 一切都以 10 为底 :-D
【解决方案5】:

求任意无符号二进制表示数的范围的公式:

2 ^ (sizeof(type)*8)

【讨论】:

  • << 是左移运算符。如果将 1 位左移 n 位,则得到 2 的 n 次方。 ^ 表示 C 中的按位异或。
  • @Kay:谢谢。我不知道二的幂可能只是左移。评论 +1?
  • 这是不正确的。 C 中的整数可能有填充。
  • @2501:对于理论计算机不正确,或者对于 C 标准不正确?
  • C 标准允许在整数中填充位。你不需要一台理论计算机来证明这一点,它发生在至少一种类型的现代架构上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
相关资源
最近更新 更多