数据的存储

简介: 数据的存储

1. 数据类型介绍

char         // 字符数据类型

short       // 短整型

int         // 整形

long         // 长整型

long long   // 更长的整形

float       // 单精度浮点数

double       // 双精度浮点数

字符存储的时候,存储的是ASCII码。

2. 整形在内存中的存储

一个变量的创建是要在内存中开辟空间的。空间的大小是根据不同的类型而决定的。

2.1 原码、反码、补码

计算机中的整数有三种 2 进制表示方法,即原码、反码和补码。

三种表示方法均有 符号位 和 数值位 两部分,符号位都是用 0 表示 “ 正 ” ,用 1 表示 “ 负 ” ,而数值位

正数的原、反、补码都相同。

负整数的三种表示方法各不相同:

原码

直接将数值按照正负数的形式翻译成二进制就可以得到原码。

反码

将原码的符号位不变,其他位依次按位取反就可以得到反码。

补码

反码 +1 就得到补码。

对于整形来说:数据存放内存中其实存放的是补码。

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统

一处理;

2.2 大小端介绍

大端(存储)模式 ,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址

中;

小端(存储)模式 ,是指数据的低位保存在内存的低地址中,而数据的高位 , ,保存在内存的高地

址中。

百度 2015 年系统工程师笔试题:

请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。

//代码1
#include <stdio.h>
int check_sys()
{
 int i = 1;
 return (*(char *)&i);
}
int main()
{
 int ret = check_sys();
 if(ret == 1)
 {
 printf("小端\n");
 }
 else
 {
 printf("大端\n");
 }
 return 0;
}
//代码2
int check_sys()
{
 union
 {
 int i;
 char c;
 }un;
 un.i = 1;
 return un.c;
}

3. 浮点型在内存中的存储

3.1浮点数存储的例子

int main()
{
 int n = 9;
 float *pFloat = (float *)&n;
 printf("n的值为:%d\n",n);
 printf("*pFloat的值为:%f\n",*pFloat);
 *pFloat = 9.0;
 printf("num的值为:%d\n",n);
 printf("*pFloat的值为:%f\n",*pFloat);
 return 0;
}

让我猜猜大家的答案是不是这个:

n 的值为:9

*pFloat 的值为:9.000000

"num 的值为:9

*pFloat 的值为:9.000000

可惜了, 答案错误是错的欧,下面才是正确的答案

n 的值为:9

*pFloat 的值为:0.000000

"num 的值为:1091567616

*pFloat 的值为:9.000000

那是为什么呢?

因为整型和浮点型在内存中的存储方式是有所差异的!!!

解析看最后哦!!!

3.2浮点数存储规则

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

(-1)^S * M * 2^E

(-1)^S 表示符号位,当 S=0 , V 为正数;当 S=1 , V 为负数。

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

2^E 表示指数位。

我们先来了解一下浮点数怎么转为二进制

十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。

那么,按照上面 V 的格式,可以得出 S=0 , M=1.01 , E=2 。

十进制的 -5.0 ,写成二进制是 - 101.0 ,相当于 - 1.01×2^2 。那么, S=1 , M=1.01 , E=2 。

IEEE 754 规定:

对于 32 位的浮点数,最高的 1 位是符号位 s ,接着的 8 位是指数 E ,剩下的 23 位为有效数字 M

对于 64 位的浮点数,最高的 1 位是符号位S,接着的 11 位是指数 E ,剩下的 52 位为有效数字 M

IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的就是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。(这样精度upup了)

指数E从内存中取出还可以再分成三种情况:

E不全为0或不全为1:

浮点数采用下面的规则表示,即指数 E 的计算值减去 127 (或 1023 ),得到真实值,再将有效数字M 前加上第一位的 1 。

E全为0 :

浮点数的指数 E 等于 1-127 (或者 1-1023 )即为真实值,有效数字M 不再加上第一位的 1 ,而是还原为 0.xxxxxx 的小数。这样做是为了表示 ±0 ,以及接近于0的很小的数字。

E全为1:

如果有效数字M全为0,表示±无穷大(正负取决于符号位s)。  

最后我们来解释一下上面的题目为什么是那个答案:

为什么 0x00000009 还原成浮点数,就成了 0.000000

首先,将 0x00000009 拆分,得到第一位符号位 s=0 ,后面 8 位的指数 E=00000000 , 最后23 位的有效数字 M=000 0000 0000 0000 0000 1001 。

9 -> 0000 0000 0000 0000 0000 0000 0000 1001

由于指数 E 全为 0 ,所以符合上一节的第二种情况。因此,浮点数 V 就写成:

  V=( - 1)^0 × 0.00000000000000000001001×2^( - 126)=1.001×2^( - 146)

显然, V 是一个很小的接近于 0 的正数,所以用十进制小数表示就是 0.000000

请问浮点数9.0,如何用二进制表示?还原成十进制又是多少?

首先,浮点数 9.0 等于二进制的 1001.0 ,即 1.001×2^3 。

9.0 -> 1001.0 -> ( - 1 ) ^01 . 0012 ^3 -> s = 0 , M = 1.001 , E = 3 + 127 = 130

第一位的符号位 s=0 ,有效数字 M 等于 001 后面再加 20 个 0 ,凑满 23 位,指数 E 等于 3+127=130 ,

即 10000010, 所以,写成二进制形式,应该是s+E+M ,即

0 10000010 001 0000 0000 0000 0000 0000

这个32位的二进制数,还原成十进制,正是 1091567616 。

❤️结语:


本次精彩内容已圆满结束!希望各位读者在阅读过程中能够收获满满。在此,特别感谢各位读者的支持与三连赞。如果文章中存在任何问题或不足之处,欢迎在评论区留言,蜗牛必定会认真对待并加以改进,以便为大家呈现更优质的文章。你们的支持与鼓励,将是博主不断前进的最大动力。再次感谢大家的陪伴与支持!


相关文章
|
21天前
|
存储 C语言
数据在内存中的存储2
数据在内存中的存储2
|
7月前
|
存储
【数据的存储】
【数据的存储】
47 0
|
10月前
|
存储
数据的存储
数据的存储
61 0
|
7月前
|
存储 小程序 编译器
数据的存储(上)
数据的存储(上)
|
7月前
|
存储
数据的存储(下)
数据的存储(下)
|
6月前
|
存储 编译器 C++
剖析数据在内存中的存储(下)
剖析数据在内存中的存储(下)
18 0
|
9月前
|
存储 缓存 固态存储
一文看懂存储
一文看懂存储
197 1
|
9月前
|
存储 应用服务中间件 nginx
k8s--数据存储、EmptyDir存储
k8s--数据存储、EmptyDir存储
|
9月前
|
存储 监控 安全
使用阿里云存储
使用阿里云存储
75 1
|
10月前
|
存储 小程序 编译器
数据在内存中的存储形式
数据在内存中的存储形式