当前位置: C语言 -- 专题 -- 有符号整数

有符号整数

本文以32位有符号整数为例,讨论有符号整数的存储与运算。


一、基本概念

现代计算机系统中有符号整数通常以二进制补码(two's complement)形式表示,其中最高位为符号位;最高位为0时,表示正数;为1时,表示负数;其余位为数值位。


1、原码

以整数1053为例,1053的二进制形式为:

低位
1053 % 2  余数为: 1
526 % 2  余数为: 0
263 % 2  余数为: 1
131 % 2  余数为: 1
65 % 2  余数为: 1
32 % 2  余数为: 0
16 % 2  余数为: 0
8 % 2  余数为: 0
4 % 2  余数为: 0
2 % 2  余数为: 0
1 % 2  余数为: 1
高位

105310 = 100 0001 11012


32位有符号整数1053的原码:

因为是正数,所以最高位为0;其余位补0

1053原码 = 0000 0000 0000 0000 0000 0100 0001 11012


32位有符号整数-1053的原码:

因为是负数,所以最高位为1;其余位补0

-1053原码 = 1000 0000 0000 0000 0000 0100 0001 11012


2、反码

正整数的反码和原码相同。

负整数的反码是原码符号位保持不变,数值位取反(即0变成1,1变成0。)。

32位有符号整数1053的反码:

1053反码 = 0000 0000 0000 0000 0000 0100 0001 11012

32位有符号整数-1053的反码:

-1053反码 = 1111 1111 1111 1111 1111 1011 1110 00102


3、补码

正整数的补码和原码相同。

负整数的补码是反码数值最低位加1

32位有符号整数1053的补码:

1053补码 = 0000 0000 0000 0000 0000 0100 0001 11012

32位有符号整数-1053的补码:

-1053补码 = 1111 1111 1111 1111 1111 1011 1110 00112


二、补码转换为十进制数

将补码转换为熟悉的十进制,首先需要判断整数是正数还是负数。如果是正数,原码和补码相同,可直接算出十进制数。如果是负数,将补码减1后,数值位取反,得到原码,再算出十进制数。


1:有符号整数X的补码为0111 0000 0000 0000 0000 0000 1110 0010,求对应的十进制整数。

符号位为0,所以X是正整数;原码和补码相同。

X10 = 1×230+1×229+1×228+1×27+1×26+1×25+1×21

  = 1879048418


2:有符号整数Y的补码为1111 1111 1111 1111 1111 1111 0010 0010,求对应的十进制整数。

符号位为1,所以Y是负整数;原码等于补码减1后,数值位取反。

Y原码 = 1000 0000 0000 0000 0000 0000 1101 11102

Y10 = -(1×27+1×26+1×24+1×23+1×22+1×21)

  = -222


上述两个例子可以通过以下代码进行验证。

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
#include <stdio.h>

int main(void)
{
    int X = 0x700000E2;
    int Y = 0xFFFFFF22;

    printf("X = %d\n", X);
    printf("Y = %d\n", Y);

    return 0;
}