浮点数转换16进制_C语⾔浮点数float类型的秘密
1 前⾔
我们在学习 C 语⾔时,通常认为浮点数和⼩数是等价的,并没有严格区分它们的概念,这也并没有影响到我们的学习,原因就是浮点数和⼩数是绑定在⼀起的,只有⼩数才使⽤浮点格式来存储。
其实,整数和⼩数可以都使⽤定点格式来存储,也可以都使⽤浮点格式来存储,但实际情况却是,C 语⾔使⽤定点格式存储整数,使⽤浮点格式存储⼩数,这是在 “数值范围” 和 “数值精度” 两项重要指标之间追求平衡的结果。
2 什么是浮点数?
浮点型简单讲就是实数的意思。浮点数在计算机中⽤以近似表⽰任意某个实数。具体的说,这个实数由⼀个整数或定点数(即尾数)乘以某个基数(计算机中通常是 2)的整数次幂得到,这种表⽰⽅法类似于基数为 10 的科学记数法。
3 浮点数在内存中的存储
⾸先明确⼀点,⽆论是整型、浮点型还是字符等等数据类型在计算机底层都是以⼆进制的⽅式存储的。
浮点数在内存中的存储和整数不同,因为整数都可以转换为⼀⼀对应的⼆进制数据。⽽浮点数的存储是由符号位 (sign) + 指数位(exponent) + ⼩数位 (fraction) 组成。
类型符号位指数尾数
Float1位(第31位)8位(第23~30位)23位(第0~22位)
Double1位(第63位)11位(第52~62位)52位(第0~51位)
int 和 float 同样占据四个字节的内存,但是 float 所能表⽰的最⼤值⽐ int ⼤得多,其根本原因是浮点数在内存中是以指数的⽅式存储。浮点数转换到内存中存储的步骤分为如下三步:
将浮点数转换成⼆进制
⽤科学计数法表⽰⼆进制浮点数
计算指数偏移后的值
对于第3点:计算指数时需要加上偏移量(后⾯有介绍为什么使⽤偏移量),⽽偏移量的值与浮点数的类型有关( float 偏移量值为 127
浮点数的基数什么意思,double 偏移量值为 1023)。⽐⽅对于指数 6,float 与 double 类型偏移后的值分别为:
float : 127 + 6 = 133
double:1023 + 6 = 1029
4 实例
浮点数19.625⽤float是如何存储的:
将浮点数转换成⼆进制:10011.101(将 19.625 整数部分采⽤除 2 取余,⼩数部分采⽤乘 2 取整法);
⽤科学计数法表⽰⼆进制浮点数:1.0011101*2^4;
计算指数偏移后的值:127 + 4 = 131  (10000011);
拼接综上所述,float 类型的 19.625 在内存中的值为:0 - 10000011 - 001 1101 0000 0000 0000 0000。
5 float与double范围和精度
范围
float和double的范围是由指数的位数来决定的。(因为表⽰的时候都是1.x * 2^Y的形式,所以忽略了1.x的效果,直接取指数表⽰浮点数的范围)
float:
1bit(符号位) 8bits(指数位) 23bits(尾数位)
double:
1bit(符号位) 11bits(指数位) 52bits(尾数位)
于是,float的指数范围为-127~+128,⽽double的指数范围为-1023~+1024,并且指数位是按补码的
形式来划分的。
其中负指数决定了浮点数所能表达的绝对值最⼩的⾮零数;⽽正指数决定了浮点数所能表达的绝对值最⼤的数,也即决定了浮点数的取值范围。
float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;
double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。
精度
float和double的精度是由尾数的位数来决定的,尾数越多能表⽰的⼩数点后⾯有效数字就越多,因此精度就越⾼。浮点数在内存中是按科学计数法来存储的,其整数部分始终是⼀个隐含着的“1”,由于它是不变的,故不能对精度造成影响。
float:2^23 = 8388608,⼀共七位,这意味着最多能有 7 位有效数字,但绝对能保证的为 6 位,也即float的精度为 6~7 位有效数字;double:2^52 = 4503599627370496,⼀共 16 位,同理,double的精度为 15~16 位。
6 解剖:为什么要⽤偏移量的⽅式来计算指数?
如果不采⽤偏移量的⽅式:
8 位 2 进制数表⽰的有符号数范围有两个区间:0000 0000~0111 1111和1000 0000~1111 1111,分别为0~+127和-127~0。
⼤家看到这⾥的问题了吧,有两个 0 ,⼀个正 0 和⼀个负 0。
如果采⽤偏移量的⽅式:
127 转化为⼆进制是:0111 1111
那么
当我们要表⽰ -127,则有127-127即0111 1111 - 0111 1111 = 0000 0000
当我们要表⽰ -126,则有127-126即0111 1111 - 0111 1110 = 0000 0001
当我们要表⽰ -2,则有127-2即0111 1111 - 0000 0010 = 0111 1101
当我们要表⽰ -1,则有127-1即0111 1111 - 0000 0001 = 0111 1110
当我们要表⽰ 0,则有0+127即0000 0000 + 0111 1111 = 0111 1111
当我们要表⽰ 1,则有1+127即0000 0001 + 0111 1111 = 1000 0000
当我们要表⽰ 2,则有1+127即0000 0010 + 0111 1111 = 1000 0001
当我们要表⽰128,则有128+127即1000 0000 + 0111 1111 = 1111 1111
由上⾯的例⼦,我们可以得出规律,采⽤移位存储技术,我们可以使⽤ 8 位⼆进制来表⽰从-127~+128共计 127 个负数+零(0)+ 128 个正数总共 256 个数,看来使⽤移位存储既没有 +0 和 -0 的问题,⼜能充分使⽤新⽣成的8位⼆进制数最⼤限度的表⽰单精度浮点数的幂指数,是⾮常合理的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。