整形及浮点数在内存的存储规则

发布于:2022-12-28 ⋅ 阅读:(362) ⋅ 点赞:(0)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

提示:这里可以添加本文要记录的大概内容:

很多人往往认为整形和浮点数在内存中的存储是相同的,其实结果正好相反,整形和浮点数在内存中的存储规则并不同,而且浮点数的存储规则更多。下面我就以简单的方式教大家快速理解整形及浮点数的存储。


提示:以下是本篇文章正文内容,下面案例可供参考

一、整形及浮点数的大致介绍

整形分为有符号整形和无符号整形:

char : unsigned char        signed char

int :   unsigned int            signed int

long : unsigned long        signed long

大多数情况下编译器默认char int long等为有符号类型。计算机中的整数有三种二进制表示方法,分别是原码,反码,补码,而在内存中存储的便是补码,在进行运算的时候也是用补码进行计算。三种表示方法均是最高位为符号位,剩余为数值位。比如

 为什么计算机中用补码存储呢?原因是使用补码可以将符号位和数值域统一处理,并且加法和减法也可以统一处理,在这声明一下cpu只有加法器,此外原码和补码相互转换,其运算过程是相同的,不需要额外的硬件电路。比如int c = 1-1在用补码计算时其实是int c = 1+(-1),在原反补的相互转化过程中,补码到原码可以有两种方法。

第一种:补码-1得到反码,然后反码符号位不变其他按位取反得到原码

第二种:补码符号位不变其他按位取反得到反码,反码+1得到原码。

同时刚刚在上图可以发现将-10的补码转化为16进制是ff ff ff f6,而在内存中是f6 ff ff ff,为什么会反呢?原因是各种编译器在取内存中数据的时候并不相同,有的从大的开始有的从小的开始,这就引入了大小端模式:

小端模式:将低位字节放到高地址。什么是低字节呢?如一百二十三这个整数,1是百位是高位,三是个位是低位。例:0x11223344    11是高位   44是低位。假设地址左边为低地址,右边为高地址:

 将低位放入低地址为小端模式  , 相反将低位放入高地址为大端模式。这也就解释了刚刚看-10的内存为何相反,原因是我的编译器用的是小端存储。

那么如何判断自己的编译器用的是大端还是小端呢?以下给出两个方案:

#include <stdio.h>
int Judge()
{
 int a = 1;
return *(char*)&a;
}
int main()
{
int ret = Judge();
if (ret==1)
{
  printf("小端\n");
}
else
{
 printf("大端\n");
}
return 0;
}

    

#include <stdio.h>
int main()
{
int a = 1;
char*p = (char*)&a;
if (*p==1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
}

2.浮点数的介绍。

 根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数可以表示成以下形式:

(-1)^S*M*2^E   s表示符号位,当s为0数为正,s为1是负数。

M表示有效数字,大于等于1,小于等于2.

2^E表示指数位

IEEE754规定,对于32位的浮点数,最高的1位为符号位s,接着的8位是指数E,剩下的23位为有效数字M。如图所示:

 IEEE754规定,对于64位的浮点数,最高的1位为符号位s,接着的11位是指数E,剩下的52位为有效数字M。如图所示:

 

 前面说过,M>=1&&M<2,那么M可以写成1.****的形式,IEEE754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存小数点后面的数,等到读的时候,再把刚刚舍去的1加上去,这样做的目的是节省一位有效数字来使小数点后面的精度更高。

举个例子:

 

 

至于指数E,IEEE754规定存入内存时E的真实值必须再加1个中间数,对于8位的E,这个中间值为127,对于11位的E,这个中间值为1023。比如,2^10中E为10,那么在保存32位浮点数时再加上127结果为137,即1001001.然而,指数E从内存中取出又分为三种情况:

第一种:E不全为0或不全为1

指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。比如0.5的二进制为0.1,由于规定正数部分必须为1,所以将小数点向右移1位,变成1*2^(-1),E为(-1)+127==126,表示为011111110  二进制表示:0 01111110 00000000000000000000000

第二种:E全为0

指数E等于1-127(或-1023)得到真实值

第三种:E全为1

这时有效数字M全为0,表示正负无穷大,正负看符号位。

二、例题讲解

1.整形例题

代码如下(示例):

 %u打印无符号整形,认为内存中存放的补码对应的是一个无符号数。

%d打印有符号整形,认为内存中存放的补码对应的是一个有符号数。

2.浮点数例题

代码如下(示例):


 

总结:
整形在内存中的存储和浮点数在内存中的存储并不相同,浮点数在内存中的存储比起整形来说规则更多,想要理解还需要自己去亲手实验一遍。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到