有符号整数与无符号整数


395

我是否正确地说带符号整数和无符号整数之间的区别是:

  1. 无符号的可以具有较大的正值,而不能为负值。
  2. Unsigned使用前导位作为值的一部分,而signed版本使用最左边的位来标识数字是正数还是负数。
  3. 有符号整数可以同时包含正数和负数。

还有其他区别吗?


6
因为0既不是正数也不是负数,所以对于无符号整数,更适合使用术语非负值代替正值
丹尼尔(Daniel)

Answers:


344

无符号的可以具有较大的正值,而不能为负值。

是。

Unsigned使用前导位作为值的一部分,而signed版本使用最左边的位来标识数字是正数还是负数。

有多种表示有符号整数的方法。最简单的可视化方法是将最左边的位用作标志(符号和大小),但更常见的是二进制补码。两者都在大多数现代微处理器中使用-浮点使用符号和幅度,而整数算术使用二进制补码。

有符号整数可以同时包含正数和负数。


我不确定这是否就是该文本,但是我找到了另一个链接。转到PDF的第9页(实际上是本书的第38页),您可以看到名为“数据表示形式”的部分(1.3节)。它具有上述所有内容的解释。lms.uop.edu.jo/lms/pluginfile.php/2420/mod_resource/content/1/…–
WeirdElfB0y

92

我将在x86的硬件级别上进行讨论。除非您正在编写编译器或使用汇编语言,否则这几乎是无关紧要的。但是很高兴知道。

首先,x86 对带符号的数字的二进制补码表示法具有原生支持。您可以使用其他表示形式,但这将需要更多说明,并且通常会浪费处理器时间。

“本地支持”是什么意思?基本上,我的意思是,有一组指令用于无符号数字,另一组用于签名数字。无符号数字可以与有符号数字位于相同的寄存器中,实际上您可以混合使用有符号和无符号指令,而不必担心处理器。由编译器(或汇编程序员)决定是否对数字签名,并使用适当的指令。

首先,二进制补码具有以下性质:加法和减法与无符号数相同。数字是正数还是负数都没有关系。(因此,您只需继续操作ADDSUB您的电话号码便不用担心。)

在进行比较时,差异开始显示出来。x86有一种区分它们的简单方法:上方/下方表示无符号比较,大于/小于表示有符号比较。(例如,JAE表示“如果等于或大于则跳转”,并且没有符号。)

还有两组乘法和除法指令,用于处理有符号和无符号整数。

最后:如果要检查(例如)溢出,则对带符号的和无符号的数字将做不同的处理。


您所说的无符号和有符号数字是什么意思,我想问的是我是否写unsigned int a = 2和signed int b = 2,所以它们都是带符号的还是无符号的,请问数字是带符号的还是无符号的,取决于类型我们将其分配给还是取决于它是否带有负号?这一直困扰着我一段时间。
Suraj Jain

@SurajJain已签名未签名是指类型。它们指示变量或表达式是否可能具有负值。
Artelius '16

我有以下疑问,我已经问过这个问题,还没有令人满意的答案,在这里看看,stackoverflow.com
41399092/…

62

他只询问已签名和未签名。不知道为什么人们会在其中添加额外的内容。让我告诉你答案。

  1. 无符号:它仅包含非负值,即0到255。

  2. 有符号:由负值和正值组成,但格式不同,例如

    • 0至+127
    • -1至-128

并且此说明是关于8位数字系统的。


17

完整性的几点说明:

  • 这个答案只讨论整数表示。对于浮点数可能还有其他答案;

  • 负数的表示形式可能有所不同。今天使用的最常见的(到目前为止-如今几乎是通用的)是二进制补码。其他表示形式包括补码(非常稀有)和带符号的幅度(极少出现-可能仅用于博物馆作品),其使用高位作为符号指示符,其余位表示数字的绝对值。

  • 当使用二进制补码时,该变量可以表示比正数更大的负数范围(乘以一)。这是因为“正数”中包括零(因为未将符号位设置为零),而没有负数。这意味着不能表示最小负数的绝对值。

  • 使用补码或带符号的幅度时,可以将零表示为正数或负数(这是通常不使用这些表示法的几个原因之一)。


如果我写unsigned int a = -2,而signed int b = -2,底层表示形式是否相同,我知道让unsigned number给出负值并不好,但是如果我给它,那将是什么呢?底层表示?
Suraj Jain

1
小小麻烦:在IEEE浮点中使用符号和幅度,因此实际上很常见。:-)
alastair

14

根据我们在课堂上学到的知识,有符号整数可以表示正数负数,而无符号整数只能是非负数。

例如,查看一个8位数字:

无符号0255

有符号值范围从-128127


11

除了第2点,其他所有内容都是正确的。有符号int有许多不同的表示法,有些实现使用第一个,另一些使用最后一个,而另一些使用完全不同的东西。这一切都取决于您使用的平台。


那是小端又大端的东西吗?
vIceBerg,

小字节序和大字节序与平台上字节的顺序有关。小字节序可能会做0xFF 0xFE 0x7F,而大字节序可能会做0x7F 0xFE 0xFF。
Jasper Bekkers,

10

另一个区别是在不同大小的整数之间进行转换时。

例如,如果您要从字节流中提取一个整数(为简单起见,请使用16位),并使用无符号值,则可以执行以下操作:

i = ((int) b[j]) << 8 | b[j+1]

(可能应该转换第二个字节,但我猜编译器会做正确的事情)

对于带符号的值,您将不得不担心符号扩展并执行以下操作:

i = (((int) b[i]) & 0xFF) << 8 | ((int) b[i+1]) & 0xFF

5

一般来说,这是正确的。如果不知道为什么要寻找差异,我就不会想到有符号和无符号之间的任何其他差异。


4

除了其他人所说的,在C语言中,您不能溢出一个无符号整数。该行为定义为模算术。您可以溢出一个有符号整数,并且从理论上讲(尽管实际上在当前主流系统上不是这样),该溢出可能会触发故障(也许类似于被零故障除以)。


1
请注意,带符号的整数溢出确实会触发未定义的行为,现代编译器在发现它并利用意想不到的但技术上合法的方式利用它来修改程序方面过于激进,因为粗略地说,它们被允许假定不会发生未定义的行为。与7年前相比,现在的问题更多了。
Jonathan Leffler

4
  1. 是的,无符号整数可以存储较大的值。
  2. 不,有多种显示正值和负值的方法。
  3. 是的,带符号整数可以同时包含正值和负值。

4

(回答第二个问题)仅使用一个符号位(而不是2的补码),就可以得到-0。不太漂亮


只需添加到这个答案,基本上就意味着10 == 00其中两个这些数字基地2

4

C中的带符号整数表示数字。如果ab是带符号整数类型的变量,则该标准绝不需要编译器将表达式a+=b存储到a它们各自值的算术和之外的任何内容中。可以肯定的是,如果算术和不适合a,则处理器可能无法将其放入其中,但是标准将不需要编译器截断或包装该值,或者如果值超过该值,则无需执行其他任何操作其类型的限制。请注意,尽管标准不需要它,但是允许C实现使用带符号的值捕获算术溢出。

C中的无符号整数表现为整数的抽象代数环,这些整数代数以2的幂为模,除非涉及到转换为较大类型或对其进行运算的情况。将任意大小的整数转换为32位无符号类型将产生与该整数mod 4,294,967,296对应的对象对应的成员。从2中减去3的原因是4,294,967,295,这是因为将与3一致的东西加到4,294,967,295的一致性会得到与2一致的东西。

抽象的代数环类型通常很方便。不幸的是,C使用符号作为类型是否应作为环的决定因素。更糟糕的是,将无符号值转换为较大类型时将其视为数字,而不是环成员,而int对它们执行任何算术运算时,会将无符号值小于转换为数字。如果vuint32_t等于4,294,967,294,那么v*=v;应该做v=4。不幸的是,如果int是64位,则无法确定该v*=v;怎么做。

给定目前的标准,我建议在需要与代数环相关的行为的情况下使用无符号类型,而在要表示数字时使用有符号类型。不幸的是,C像以前那样区分了它们,但它们就是它们。


3

与有符号整数相比,无符号整数更容易在特定陷阱中吸引您。陷阱来自以下事实:虽然上面的1和3是正确的,但是可以为两种类型的整数分配一个超出其“保持”范围的值,并且将对其进行静默转换。

unsigned int ui = -1;
signed int si = -1;

if (ui < 0) {
    printf("unsigned < 0\n");
}
if (si < 0) {
    printf("signed < 0\n");
}
if (ui == si) {
    printf("%d == %d\n", ui, si);
    printf("%ud == %ud\n", ui, si);
}

运行此命令时,即使两个值都被分配为-1并以不同的方式声明,也将获得以下输出。

signed < 0
-1 == -1
4294967295d == 4294967295d

0

C中有符号和无符号值之间唯一可以保证的区别是,有符号值可以为负,0或正,而无符号只能为0或正。问题在于C没有定义类型的格式(因此您不知道您的整数是二进制补码)。严格来说,您提到的前两点是错误的。


0

在嵌入式系统上进行编程时,必须使用无符号整数。在循环中,当不需要有符号整数时,使用无符号整数将节省设计此类系统所需的安全性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.