数据类型 |
您所在的位置:网站首页 › float型几个字节 › 数据类型 |
1. 数据类型
1.1 类型分类
在C语言中,数据类型分为 整型,浮点型,自定义,指针和空类型 整型 char //字符 short //短整型 int //整形 long //长整型 long long //更长的整形浮点型 float //单精度浮点数 double //双精度浮点数 自定义类型 数组 结构 枚举 联合 指针类型 int* pa // 整型指针 char *pc; float* pf; void* pv; // 空指针 空类型 空类型void, 表示无类型 2. 整型 2.1 整型分类
整型根据有无符号分为两类,有符号整型,和无符号整型 char unsigned char signed char short unsigned short [int] signed short [int] int unsigned int signed int long unsigned long [int] signed long [int]有符号整型
有符号整型,可以存储整数和负数,用最高位作符号位,1表示 - , 0 表示 +, 其余位作数值位
例子:
char存储一个字节,8个比特位
1 000 0001 = -1 最高位1,表示 -
0 000 0001 = 1 最高位0,表示 +
无符号整型
无符号整型,只能存储正数,全部的位都是数值位
例子:
1 000 0001 = 129 无符号整型,所有的位是数值位
0 000 0001 = 1
2.2 整数在内存中的存储
整数,分正数和负数 正数的存储 计算机内存直接存储一个正数的二进制
例子: #include int main() { int a = 20; return 0; }
解析: 变量a为整型, 存储4个字节, 32个比特位 十进制20转换为二进制: 0000 0000 0000 0000 0000 0000 0001 0100 转换为16进制: 00 00 00 14 负数的存储
要理解负数在内存中的存储,首先要知道 原码,反码,补码 原码 将一个数,转换为二进制,就是原码
反码 将原码的符号位不变,其他位按位取反
补码 反码+1,得到补码
例子: -10的原码:1 000 0000 0000 0000 0000 0000 0000 1010 转二进制 -10的反码:1 111 1111 1111 1111 1111 1111 1111 0101 除最高位不变,其他位按位取反 -10的补码:1 111 1111 1111 1111 1111 1111 1111 0110 取反 + 1 以十六表示为:FF FF FF F6 #include int main() { int b = -10; return 0; }
2.3 计算机内存存储补码
整数在计算机内存中实际存储的是补码
正数的原码,反码,补码相同 负数的补码,需要转换
例子: #include int main() { int a = 20; int b = -10; return 0; }
为什么负数得到补码要转换
方便进行减法运算
例子:
计算 1 - 1
思路 将 1 - 1, 转换为 1 + (- 1)
1为正数,原码,反码,补码相同 00000000 00000000 00000000 00000001
-1为负数,转换 10000000 00000000 00000000 00000001 原码 11111111 11111111 11111111 11111110 反码 11111111 11111111 11111111 11111111 补码
1 + (- 1): 00000000 00000000 00000000 00000001 + 11111111 11111111 11111111 11111111 = 00000000 00000000 00000000 00000000
解析: 进位的1会到33位上,int 为4个字节,只能存32位,所以得0
2.4 为什么要用补码进行存储和计算
计算机是一个电子器件,由一个个逻辑门逐步抽象组成 如果用补码进行计算,只需加法器就可以实现 加,减, 乘, 除 运算,因为乘除相当于多次的加法或减法
这里 B 通过 反相器 inv 16 取反, 增量器 inc 16 +1, 得到 -1的补码, 然后通过全加器adder 16 进行加法运算
3. 浮点数 3.1 浮点数的表示
IEEE 754, 规定任意 二进制浮点数 以 (-1) S * M * 2E 形式 进行表示 解析
S 表示符号位,S 为0 表示正,为1表示负 S = 0, (-1)0 = 1 S = 1, (-1)1 = -1
M 表示 有效数位
E 表示 指数位
例子
以 5.5 为例:
首先,将5.5转换为二进制,等于 101.1
解: 1*22 + 0*21 + 1*20 + 1 * 2-1 = 4 + 0 + 1 + 0.5 = 5.5
然后,转换为科学计数法 = 1.011 * 22
最后,代入浮点数表示形式 (-1) S * M * 2E = (-1)0 * 1.011 * 22
S = 0, M = 1.011, E = 2
3.2 浮点数存储模型
float 单精度浮点型, 存储4个字节,32个比特位 double 双精度浮点型, 存储8个字节,64个比特位
3.3 浮点数的存储规则 符号位S的存储规则
用1位作符号位,负存储1,正存0
S = 0, (-1)0 = 1 S = 1, (-1)1 = -1 指数位E的存储规则
存储指数位E时,根据类型加上一个中间值,float + 127 , double + 1023 这是因为E有可能是负数
例子:
以 0.1 为例 转换为科学计数法 = 1.0 * 2-1 此时,E = -1
所以,存储时需要加上中间值,确保是正 有效数值M的存储规则
有效数值M,存储小数位
例子: 5.5 - > 101.1 - > 1.011 * 22
内存中实际存储 : M ---> 011 0000 0000 0000 0000 0000 缺位补0 实例 #include int main() { float a = 5.5; return 0; }
解析 5.5 - > 101.1 - > 1.011 * 22
表示: (-1)0 * 1.011 * 22
存储: S ---> 0 E, 2+127 ---> 1000 0001 M, ---> 011 0000 0000 0000 0000 0000 = 0100 0000 1011 0000 0000 0000 0000 0000 转换为 16进制:0x 40 b0 00 00 4. 类型的意义 4.1 类型决定开辟内存的大小
类型,决定开辟内存空间的大小 整型 int,开辟4个字节,32个比特位 短整型 short, 开辟 2个字节,16个比特位 4.2 类型决定看待内存的视角 #include int main() { int n = 9; float* pFloat = (float*)&n; printf("%d\n", n); printf("%f\n", *pFloat); *pFloat = 9.0; printf("%d\n", n); printf("%f\n", *pFloat); return 0; }
解析
1. 首先, int存储4个字节, 9, 为正数, 原码, 反码,相同 , 实际内存中存储 ---> 00000000 00000000 00000000 00001001 2. 单精度浮点型指针 pfloat,存储n的内存地址 3. 打印十进制有符号整型, 此时,以有符号整型的视角看待内存,最高位=0, 正数, 既然是正数,表示原,反,补相同,打印 9 如果最高位为1,负数,需要 取反+1 或 -1 取反 得到原码,再进行打印
4. 打印有符号单精度浮点数,此时,以浮点数的视角看待内存 ---> 0 00000000 00000000000000000001001 符号位S = 0, 表示正 指数位E = -127 有效数值位 M = 00000000000000000001001 (-1)0 * 0. 00000000000000000001001 * 2 -127
这是一个无限接近于0的数,所以 打印 0.000000
5. *pFloat = 9.0,使用指针访问内存单元,以浮点数的形式,存储9.0
转换: 9.0 ---> 1001.0 --> 1.0010 * 23 S = 0, E= 3, M = 0010 ,E = 3 ---> 0 10000010 00100000000000000000000
此时,内存中的存储 ---> 0 10000010 00100000000000000000000
6. 打印十进制有符号整型, 以有符号整型的视角看待内存 ---> 0 10000010 00100000000000000000000 = 1,091,567,616 7. 打印有符号单精度浮点数, 以有符号单精度浮点数视角看待内存 ---> 0 10000010 00100000000000000000000 S = 0, E = 130 - 127 = 3, M = 001 ---> 1.001 * 23 ---> 9 以单精度浮点数打印 ---> 9.000000
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |