有符号整数和无符号整数之间的区别是:
Unsigned值可以是一个较大的正数,而不能是负数。 Unsigned版本使用前导位作为值的一部分,而signed版本使用最左边的位来识别数字是正还是负。 有符号整数可以同时包含正数和负数。
还有其他区别吗?
有符号整数和无符号整数之间的区别是:
Unsigned值可以是一个较大的正数,而不能是负数。 Unsigned版本使用前导位作为值的一部分,而signed版本使用最左边的位来识别数字是正还是负。 有符号整数可以同时包含正数和负数。
还有其他区别吗?
当前回答
无符号整数比有符号整数更容易让您陷入特定的陷阱。陷阱来自于这样一个事实:虽然上面的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
其他回答
是的,无符号整数可以存储大的值。 不,有不同的方式来表示正数和负数。 是的,有符号整数可以包含正数和负数。
我将在x86上讨论硬件层面的差异。除非您正在编写编译器或使用汇编语言,否则这几乎无关紧要。但很高兴知道。
首先,x86原生支持这两个数字的有符号数的补表示。您可以使用其他表示,但这将需要更多的指令,通常是浪费处理器时间。
我所说的“原生支持”是什么意思?我的意思是,有一组指令用于无符号数,另一组用于有符号数。无符号数可以与有符号数位于相同的寄存器中,实际上,您可以混合有符号和无符号指令,而不用担心处理器。由编译器(或汇编程序员)来跟踪数字是否带符号,并使用适当的指令。
首先,2的补数具有加减法与无符号数相同的性质。这些数字是正还是负没有区别。(所以你只要继续做加法和减法就可以了,不用担心。)
当进行比较时,差异开始显现出来。X86有一种简单的区分方法:上面/下面表示无符号比较,而大于/小于表示有符号比较。(例如,JAE的意思是“高于或等于就跳”,没有符号。)
还有两组乘除指令用于处理有符号整数和无符号整数。
最后:如果你想检查溢出,你可以对有符号数和无符号数做不同的检查。
在C语言中,有符号值和无符号值之间唯一保证的区别是有符号值可以为负、0或正,而无符号值只能为0或正。问题是C语言没有定义类型的格式(所以你不知道你的整数是2的补数)。严格来说,你提到的前两点是不正确的。
(回答第二个问题)通过只使用符号位(而不是2的补码),你可以得到-0。不太漂亮。
关于这个问题,我找到的最佳答案要感谢IBM引用的XDR标准:
Integer An XDR signed integer is a 32-bit piece of data that encodes an integer in the range [-2147483648,2147483647]. The integer is represented in two's complement notation. The most and least significant bytes are 0 and 3, respectively. The data description of integers is integer. Unsigned integer An XDR unsigned integer is a 32-bit piece of data that encodes a nonnegative integer in the range [0,4294967295]. It is represented by an unsigned binary number whose most and least significant bytes are 0 and 3, respectively. The data description of unsigned integers is unsigned.
参见维基百科上的XDR标准