整数在计算机中的存储

用于存储整数的数据类型是整型(比如int),那么,整数在计算机中是以怎样的二进制代码存储的呢?

本篇将为你揭秘整数在计算机中的存储方式~

一、整数在编程时的表示方式(书写方式)

整数在编程时的表示方式按照进制不同,有三种表示方式:

  • 十进制:直接书写
  • 十六进制:前缀0X或者0x
  • 八进制:前缀0(是零不是字母O)
  • 二进制:不可以,用十六进制代替

二、为什么不直接存储整数的二进制代码

十进制的整数可以直接转化为二进制,具体见常用进制及其转化一文,对于整数的符号则用最高位来表示,这样做的优点是简单方便,但是这样做的缺点有二:

  • 直接存储导致运算(减法)的时候比较复杂,不利于CPU的硬件设计,对于加法运算没有什么影响
  • 0的表示不唯一:因为最高位是符号位,所以+0(0 0000000)和-0(1 0000000)都表示0;

三、整数以其补码存储在计算机中

1. 整数 -> 补码的规则

正整数的补码

  • 正整数的补码:直接将正整数转化为二进制即可,位数不够左边补0

eg.

在64位机器上,C语言的一个int占4个字节,则十进制正整数86存储在计算机中的补码是:00000000 00000000 00000000 01010110,用十六进制表示为0x00000056

下面编写程序来验证一下:

# include 

int main(void)
{
     
	int i = 86;

	printf("i = %d\n", i);
	printf("i = %#x\n", i);

    return 0;
}

运行结果为:

整数在计算机中的存储_第1张图片

负整数的补码

  • 负整数的补码:首先将负整数对应的正整数转化为二进制,然后将所有位取反,再加一,位数不够左边补1

eg.

在64位机器上,C语言的一个int占4个字节,则十进制负整数-86存储在计算机中的补码是:11111111 11111111 11111111 10101010,用十六进制表示为0xFFFFFFAA

下面编写程序来验证一下:

# include 

int main(void)
{
     
	int i = -86;

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

    return 0;
}

运行结果为:

测试程序运行结果

0的补码

  • 0的补码表示唯一:0

eg.

在64位机器上,C语言的一个int占4个字节,则十进制整数0存储在计算机中的补码是:00000000 00000000 00000000 00000000,用十六进制表示为0x00000000

2. 补码 -> 整数的规则

正整数补码的十进制

  • 正整数的补码:最高位为0表示正整数的补码,直接转化为十进制即可。

eg.

在64位机器上,C语言的一个int占4个字节,则存储在计算机中的补码00000000 00000000 00000000 01010110,用十六进制表示为0x00000056,对应的十进制正整数为86

下面编写程序来验证一下:

# include 

int main(void)
{
     
	int i = 0x56;

	printf("i = %d\n", i);
	printf("i = %#x\n", i);

    return 0;
}

运行结果为:

测试程序运行结果

负整数补码的十进制

  • 负整数的补码:最高位为1表示负整数的补码,将所有位(补全后的)全部取反,然后加一,得到对应的十进制数的绝对值,最后加上负号。
    eg.

在64位机器上,C语言的一个int占4个字节,存储在计算机中的补码是11111111 11111111 11111111 10101010,用十六进制表示为0xFFFFFFAA,则对应的十进制负整数为-86

下面编写程序来验证一下:

# include 

int main(void)
{
     
	int i = 0xFFFFFFAA;

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

    return 0;
}

运行结果为:

整数在计算机中的存储_第2张图片

0补码的十进制

  • 0的补码唯一,对应的十进制整数还是0。

四、关于C语言中的数据类型

通过上一节的讲述,我们知道了整数是以其补码的形式存储在计算机中的,接下来我们看一个小问题:

问题描述

同样将0x80存储在计算机中,取出来的结果却不同

# include 

int main(void)
{
     
	char i = 0x80;
	unsigned char j = 0x80;

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

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

    return 0;
}

运行结果如图:

整数在计算机中的存储_第3张图片

分析原因

这是因为同样的8位数据1000 0000存储在计算机中,但是变量的数据类型不同,所以解释的数据不同:

  • char默认是有符号,1000 0000的最高位为1,表示负数,所以将这个补码解释为负整数,即-128;
  • unsigned char是无符号的,所以将1000 0000这个补码解释为正整数,即128;

五、整数溢出

整数溢出后会从头开始计数,针对无符号整数溢出有符号整数溢出两种情况进行分析:

  • 无符号整数溢出:最高位进位,因为存储空间大小限制,超出的部分直接舍弃,所以会从0开始重新计数。
  • 有符号整数溢出:数据位进位,导致符号位变为1,数据位清零,所以会从对应的最小的负数开始重新计数。

示例程序如下:

/**
* @ brief       测试整数的溢出
* @ author      mculover666
* @ date        2019年6月26日14:42:59
* @ encoding    GBK/GB2312
*/
#include 
#include 
#include 

int main(void)
{
     
    int i = INT_MAX;
    unsigned int j = UINT_MAX;

    printf("%d %d %d\n", i, i+1, i+2);
    printf("%u %u %u\n", j, j+1, j+2);

    system("pause");
    return 0;
}
/*
    在Mingw-w64编译后运行结果:
    ------------------------------------
    2147483647 -2147483648 -2147483647
    4294967295 0 1
    请按任意键继续. . .
    ------------------------------------
*/

你可能感兴趣的:(C语言集锦,整数存储)