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