众所周知,C的float、VB的Single都是32位浮点数变量类型(也叫单精度浮点数),C的double和VB的Double则都是64位的浮点数变量类型(也叫双精度浮点数)。有些编译器还支持更屌的long double(貌似是80位还是128位的我不清楚,总之存在这种变态玩意儿。)那么这些浮点数从最底层的角度来看,它们是怎么存储的呢?我来举个例子解释下。计算机用的是二进制,如果我用二进制跟大家解释大家可能觉得看不懂,那我就用十进制来跟大家解释。
浮点数分三个部分,第一个部分是有效数字,第二个部分给出小数点的位置,第三个部分用来判断这个数是正数还是负数。举例如下:
浮点数123.456
那么它用浮点数的存储格式来表示就是:有效数字就是123456,小数点的位置在3的后面,然后它是正数。

那么我们要做的就是先取出有效数字123456,然后在3的后面插入小数点.就成了123.456,最后给它加个正号,就是+123.456了。

从二进制的方面来理解也是一样的,比如我要表示-10101010.01010101,那么它的有效数字是1010101001010101,小数点在中间,然后它是负数。
上面我都只说了“小数点在中间”、“小数点在3后面”这种比较含糊的表达方法。那么浮点数到底是怎么存储小数点的位置呢?这里我们要注意一整个浮点数中用来表示小数点位置的位数是多少。
还是用十进制来给大家举个例子。假设我用两个位来表示小数点的位置,那么两个十进制位表示的最小的数是00,最大的数是99,我们总共能表达100个值。假设我要表达1234.5678,那么情况就是如下所示的:
有效数字是12345678
小数点的位置在中间。
这里我们用两个十进制位来表示小数点的位置,那么这个小数点从左往右数(原来的数字是1234.5678)是在第四个位的后面。因此这两个十进制位的值就是03。因为00表示从左往右数的第一个位的后面,01表示从左往右数的第二个位的后面,02表示从左往右数的第三个位的后面,那么03就表示从左往右数的第四个位的后面了。
有人可能会说“但是这样一来我们不就无法表现小数了嘛。”其实不然。比如我们要表现0.233,那么我们就把有效数字设置成“0233”,然后小数点位置是00就行了。
对应的,二进制表示也是这样的,比如我们用8个二进制位来表示小数点的位置,我们要表现的小数是10101010.01010101,那么小数点在从左往右数第八个位的后面,我们就用00001000来表示小数点的位置。

这里我就需要针对性地告诉大家,float和double是怎么回事。
float浮点数的有效数字是23位,小数点用8个位表示,然后符号(正、负)用一个位表示(0表示正、1表示负),总共组成32位。
因为float浮点数用8个位表示小数点的位置,因此小数点可以有256个位置。float浮点数规定从左往右数第127位的值必须是1,然后从第128位开始才是float的23位有效数字。因此float的浮点数的23位有效数字其实是从左往右数从第128位开始的。
我这里举个例子:浮点数1.0f是怎么存储的:
0 01111111 00000000000000000000000(0x3F800000)
其中蓝色的部分是符号位,0表示正数。
黄色的部分表示小数点的位置,在从左往右数第127位处。
绿色部分是有效数字,共23个0,也就是全零。如果转换为十进制,大约就是6、7个数位左右。
按照float浮点数的特性,第127位的值必须是1,然后存储的23位有效数字的位置是在第128位开始的,我们把这个浮点数展开为256位,是这样表示的:
00000000000000000000000
前面的那些零和后面的那些零都是“虚构的”,也就是说这些零并没有被存储在float里面,而是同于补充位数的。第127位被强制设置为“1”,这是float的规定。
浮点数存储了它的小数点位置:01111111,也就是“127”这里。那么我们最终得到的浮点数是:1.0

同样的,double也是和float一样用三个部分表示浮点数:有效数字,小数点位置,符号。
double的有效数字是52位,小数点位置用11个位表示,符号位用一个位表示。十进制可以精确到16个数位左右。
我这里举个例子:浮点数1.0是怎么存储的:
0 01111111111 0000000000000000000000000000000000000000000000000000(0x3FF0000000000000)
其中蓝色的部分是符号位,0表示正数。
黄色的部分表示小数点的位置,在从左往右数第1023位处。
绿色部分是有效数字,共52个0,也就是全零。
按照double浮点数的特性,第1023位的值必须是1,然后存储的52位有效数字的位置是在第1024位开始的,我们把这个浮点数展开为2048位,是这样表示的:
0000000000000000000000000000000000000000000000000000
在这2048位的数字中,我们的double存储的52个有效数字在其中的绿色部分,也就是从1024位开始处。1023位被强制设置为1。可以看出,double的精度比起float提高了不少。
小数点的位置:01111111111表示小数点在第1023位的后面,因此最终得到的浮点数的数值是1.0

除了float和double,还有其它格式的浮点数:
Minifloat:迷你浮点数(8位):
1位符号位,4位小数点位置,3位有效数字。(PS.真够“迷你”的)
Half:半精度(16位):
1位符号位,5位小数点位置,10位有效数字。
x86 Extended Precision Format:x86扩展精度格式(80位):
1位符号位,15位小数点位置,1位特殊位,63位有效数字。特殊位请看http://en.wikipedia.org/wiki/Extended_precision
Quadruple:四倍精度(128位):
1位符号位,15位小数点位置,112位有效数字。

IEEE规定:
1、表示小数点位置的部分如果全零,那么这个浮点数的值为0,而如果这个时候有效数字部分非零,那么这个浮点数就“不是一个数”(NaN)
2、表示小数点位置的部分如果全一,那么这个浮点数的值为无穷大。
3、浮点数能表示的最大数值:表示小数点位置的部分除了最低位为零其它均为一,有效数字全为1
4、浮点数能表示的最小数值:表示小数点位置的部分除了最低位为一其它均为零,有效数字全为0

参考资料
http://en.wikipedia.org/wiki/Minifloat
http://en.wikipedia.org/wiki/Half-precision_floating-point_format
http://en.wikipedia.org/wiki/Sin ... oating-point_format
http://en.wikipedia.org/wiki/Dou ... oating-point_format
http://en.wikipedia.org/wiki/Extended_precision
http://en.wikipedia.org/wiki/Qua ... oating-point_format

https://www.0xaa55.com/forum.php?mod=viewthread&tid=462

IEEE浮点数float、double的存储结构的更多相关文章

  1. C/C++中float和double的存储结构(转)

    在C/C++中float是32位的,double是64位的,两者在内存中的存储方式和能够表示的精度均不同,目前C/C++编译器标准都遵照IEEE制定的浮点数表示法来进行float,double运算. ...

  2. float double 如何存储计算2 (这个写的也不错)

    目前java遵照IEEE制定的浮点数表示法来进行float,double运算.这种结构是一种科学计数法,用符号.指数和尾数来表示,底数定为2——即把一个浮点数表示为尾数乘以2的指数次方再添上符号. 我 ...

  3. C/C++中float和double的存储结构

    int main (int argc, char **argv) { float a = 1.0f; cout <<"(int&)a = "<<(i ...

  4. float double 如何存储

    类型float大小为4字节,即32位,内存中的存储方式如下: 符号位(1 bit)   指数(8 bit)   尾数(23 bit) 类型double大小为8字节,即64位,内存布局如下: 符号位(1 ...

  5. sql server数据库如何存储数组,int[]float[]double[]数组存储到数据库方法

    原文地址:https://www.zhaimaojun.top/Note/5475296 将数组存储到数据库的方法 (本人平时同csharp编写代码,所以本文中代码都是csharp代码,有些地方jav ...

  6. C语言中float,double类型,在内存中的结构(存储方式)

    C语言中float,double类型,在内存中的结构(存储方式)从存储结构和算法上来讲,double和float是一样的,不一样的地方仅仅是float是32位的,double是64位的,所以doubl ...

  7. Java浮点数float,bigdecimal和double精确计算的精度误差问题总结

    (转)Java浮点数float,bigdecimal和double精确计算的精度误差问题总结 1.float整数计算误差 案例:会员积分字段采用float类型,导致计算会员积分时,7位整数的数据计算结 ...

  8. C语言浮点数存储结构

    float类型占四个字节,每个字节占8位,总共32位,其内存结构如下图: 31位为符号位:0表示正数,1表示负数 31~23位:共8位表示指数位,内存存储数据从0~2^8-1=255,由于指数可以是正 ...

  9. 什么是浮点型?什么是单精度浮点数(float)以及双精度浮点数(double)?

    前言 作为一名java学习者,怎能不懂这些java基础中的基础呢?本文就带各位温顾温顾java浮点型.单精度浮点数.双精度浮点数. 浮点型 首先明确java中浮点型数据类型主要有:单精度float.双 ...

随机推荐

  1. C——货物管理系统

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> ...

  2. struts2上传下载

    struts上传下载必须引入两个jar文件: commons-fileupload-x.x.x.jar和comons-io-x.x.x.jar上传文件 import java.io.BufferedI ...

  3. Android系统智能指针的设计思路(轻量级指针、强指针、弱指针)

    本博客为原创,转载请注明出处,谢谢. 参考博文:Android系统的智能指针(轻量级指针.强指针和弱指针)的实现原理分析 C++中最容易出错的地方莫过于指针了,指针问题主要有两类,一是内存泄露,二是无 ...

  4. The process "E:\Qt\4.8.5\bin\qmake.exe" exited with code 2.(不能包含中文路径,qmake够弱智的)

    打开某个项目的时候,编译出现类似的错误 21:46:44: The process "E:\Qt\4.8.5\bin\qmake.exe" exited with code 2. ...

  5. Microsoft SQL Server 混合云博客系列

    Microsoft 云操作系统愿景的核心支柱之一就是借助我们的混合云基础结构改造数据中心.在 Windows Azure 基础结构服务正式发布后的几个月里,我们一直在发布博客,介绍 Windows A ...

  6. GCD自己做的一些简单总结

    GCD总结 GCD  Grand Central Dispatch  牛逼的中枢调度器 GCD中各种队列的执行效果 想看线程  必须是异步函数  并且不是主队列 注意:使用sync函数往当前串行队列添 ...

  7. citrix协议ICA技术原理

    转载自: http://www.zrss.com.cn/article-110-1.html Citrix交付中心解决方式的核心是虚拟化技术,虚拟化计算的核心是ICA协议,ICA协议连接了执行在平台上 ...

  8. Objective-c 数据类型

    这里列出Objective-c中独有数据类型: 一.字符串 在Objective-c中,字符串常量是由@和一对从引号括起的字符串序列.比如:@"China".@"obje ...

  9. jQuery也能舞出绚丽的界面(完结篇)

    ThematicMap又增加了两种Chart类型,现在总算是齐全了,效果也出来了,与大家分享一下: 1.MultiSelect选择界面: 颜色框是可以选择颜色的: 2.生成的饼图效果: 3.生成的柱状 ...

  10. OutLook 2010 收件箱子文件夹收到新邮件时没有桌面通知

    开始---规则----管理规则和通知 规则和通知---电子邮件规则---批量选择账号---更改规则---在新邮件通知和窗口显示(选中)---确定 录入通知邮件消息---确定 效果如下: