为什么负整数比正整数多一个?

14
任何 int 数据类型(除了 tinyint)的上限始终比下限的绝对值小1。
例如,int 的上限为 2,147,483,647,而 ABS(下限) = 2,147,483,648。
是否存在任何原因导致负数 int 大于正数 int? 编辑:问题与数据库无直接关系,已更改。

9
因为0没有+0和-0。2的32次方是偶数。你有一个0,所以你有2的31次方减1,这是奇数。你不能用相同长度同时表示正负数。 - Lukasz Szozda
2
https://en.m.wikipedia.org/wiki/Two%27s_complement - Martin Smith
3个回答

8
你提供的类型是有符号整数。让我们看一个字节(8位)的例子。使用1个字节,您有2^8种组合,可以存储256个可能的数字。
现在您想要相同数量的正数和负数(每组应该有128个)。
问题在于0没有+0-0。只有一个0
所以你最终得到范围为-128..-1..0..1..127
相同的逻辑也适用于16/32/64位
编辑:
为什么范围是-128到127
这取决于您如何表示有符号整数:
- 表示有符号幅度 - 补码 - 二进制补码

7
这并没有确切解释为什么范围不是-127至128。 - Gordon Linoff
1
谢谢lad2025,我在阅读关于二进制补码的资料后明白了原因。 - Mark He

6

这个问题与数据库没有太大关系。

正如lad2025所指出的,这些值是偶数。因此,如果包括0,则会有一个更多的正数或负数值。你问的问题似乎是:“为什么负数比正数多一个?”

基本上,原因在于符号位。一种可能的负数实现方法是将 n - 1 位用于表示绝对值,然后使用0和1表示符号位。这种方法的问题在于它允许+0和-0。这是不可取的。

为了解决这个问题,计算机科学家设计了补码表示法来表示带符号整数。(维基百科详细解释了这一点)基本上,该表示法保持了可以测试的符号位概念。但它改变了表示法。如果 +1 被表示为001,那么-1 被表示为111。也就是说,负值是正值减去一的按位取反。事实上,负值总是通过减去1并使用按位取反生成的。

问题在于100(后跟任意数量的零)。符号位被设置为负,因此它是负数。但是,当你减去1并反转时,它会再次变成本身(011 --> 100)。有一个论点认为应该将其称为“无穷大”或“非数字”。而实际上,它被赋予了可能的最小负数。


谢谢你的帮助,Gordon。我在阅读维基百科后明白了。我想你的意思是-1表示为111,而补码0表示为全0,这就是为什么负数比正数多一个的原因。再次感谢! - Mark He
@MarkHe . . . 非常感谢。我是凭记忆写的原始代码,而且已经有一段时间没有学习计算机科学课程了。我已经修正了答案。 - Gordon Linoff
这是错误的。在二进制补码中,负值始终是正值按位取反加一。它的反过来也是一样的,即在二进制补码中,正值始终是负值按位取反加一。你的引用基本上是陈述相反的结果。但它可能会让正在学习使用二进制补码表示负整数的人感到困惑。无论是从负数转换为正数还是从正数转换为负数,您总是执行反向然后加一的操作。 - ZeZNiQ

0
假设您有一个4字节(32位)整数。C++定义的范围是-231231-1。 因此,我们得到一个范围-231.....0......231。 我们可以将其视为具有231个非负整数(注意包括0)和231个负整数

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接