float 4个字节(采用IEEE754标准:标准规定了计算机程序设计环境中的二进制和十进制的浮点数自述的交换、算术格式以及方法)
浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的"1"
例如:123.45=1.2345*10^2;
一个float类型的数据在内存中的存储格式为
符号位 指数位 底数位
0 00000000 0000000 00000000 00000000
S EEEEEEEE MMMMMMM MMMMMMMM MMMMMMMM
1位 8位 23位
S: 1位,表示负数,0表示正数
E: 8位,表示指数,可表示数据范围(00000000-11111111,对应的十进制为0-255)
因为指数可以是正数也可以是负数,IEEE754标准规定:指数减去127才是实际的指数(这是规定)
float的指数表示范围是-127到128;
M: 24位(实际只存储23位),表示底数
因为所有的小数都可以表示为1.xx*10^n;小数点前面永远是1,所以小数点前面一位默认不存储,只存储小数点后面的23位
所以float的数据范围
1*-2^128到1*2^128 也即 -3.04E38~3.04E38(E表示10的几次方)
精度问题
float的底数部分由23位二进制组成
所以底数的最大值为2^23=8388607(最大为7位),所以float类型的有效数字最大为7位
double 8个字节(采用IEEE754标准)
浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的"1"
例如:123.45=1.2345*10^2;
一个double类型的数据在内存中的存储格式为
符号位 指数位 底数位
0 00000000000 0000000 00000000 00000000 00000000 00000000 00000000 00000000 0000
S EEEEEEEEEEE MMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMM
1位 11位 52位
S: 1位,表示负数,0表示正数
E: 11位,表示指数,可表示数据范围(00000000000-11111111111,对应的十进制为0-2047)
因为指数可以是正数也可以是负数,IEEE754标准规定:指数减去1023才是实际的指数(这是规定)
float的指数表示范围是-1023到1024;
M: 53位(实际只存储52位),表示底数
因为所有的小数都可以表示为1.xx*10^n;小数点前面永远是1,所以小数点前面一位默认不存储,只存储小数点后面的52位
所以double的数据范围
1*-2^1024到1*2^1024 也即 -1.798E308~1.789E308(E表示10的几次方法)
精度问题
double的底数部分由52位二进制组成
所以底数的最大值为最大值为2^52=4503599627370496(最大为16位),所以double类型的有效数字最大为16位
float数据十进制和二进制的转换
23.125转换为二进制
整数和小数部分分别转换
23的二进制
23/2 11 1
11/2 5 1
5/2 2 1
2/2 1 0
1/2 0 1
23的二进制位10111
0.125的二进制
0.625*2=1.25 取整1,小数部分0.25
0.25*2=0.5 取整0,小数部分0.5
0.5*2=1.0 取整1,小数部分0
0.125的二进制0.101
23.125的二进制10111.101
10111.101将"."向左移动,直到小数点前面只剩1位;
10111.101=1.0111101*2^4;(类比十进制数123.456=1.23456*10^2)
指数:实际为4,因为IEEE754标准规定,存储的指数减去127才是实际的指数(这是规定)
所以4+127=131转换为二进制才是存储的指数10000011
底数:0111101(只记录小数点后面即可)
所以23.125在的在内存中存储形式为
符号位 指数位 底数位
0 10000011 01111010000000000000000