权威:
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html
维基百科:
http://en.wikipedia.org/wiki/Single-precision_floating-point_format
http://en.wikipedia.org/wiki/Double-precision_floating-point_formathttp://zh.wikipedia.org/w/index.php?title=IEEE_754&oldid=32785022
底层硬件其实有两种编码形式:
规格数: 这个编码速度高(相对于非规格数的硬件实现),由于前置为1,貌似有效位更高;但是如果纯粹采用规格数,会有一个问题:单精度浮点数的绝对值下,最小规格数(2^(-126))与零(例如正零 2^(-127))的差值为2^(-126) - 2^(-127) = 2^(-127),而最小规格数与次小规格数之间的距离为2^(-126-23),精度上相差2^22,这就称之为突然式下溢出(abrupt underflow)。
非规格数是Intel的逆袭方案,其实针对DEC公司的,这种方案可以让零与最小非规格数之间的距离为2^(-127),就不会出现这种间断了。
两种方案之水火
我一开始认为,非规格数与规格数是两种竞争方案,或者在IEEE-754-1985里面是?至少在IEEE-754-2008里面,非规格数(denormal number)改名为subnormal number(从名字上,被规格数收编了),总体上还是采取规格数方案,但在接近零的数(最小规格数与零之间),采用非规格数。可以认为,这两个方案携手合作,相互相承。
两种方式的统一编码
那么,在一个二进制串里面,怎让才知道这是哪一个编码?如果指数部分为零(编码上为零,若为单精度浮点数,则为-127),有两种情况:
A. 有效数字串为零,这就是浮点数的零了。接下来,按照规格化的解释,那么加上隐藏的首位1,这个零是: 2^-127
B. 如果有效数字串不为零,我们采用非规格化解释。这个时候,注意,指数不是2^-127,而解释为2^-126,没有了隐藏的首位1了,有效字串是什么就是什么,如果是二进制串"11111",那么就被解释成 0.11111。单精度下,有效字串最小为0..01(前面有22个零),因此,绝对值意义下,最小的非规格化浮点数位2^(-23 - 126),一下子弥补了突然式下溢出的问题。
浮点编码的特点
写到这里,我同时感觉到,除了零以外,实际上,对于规格化浮点数,每次指数往上升1的前后,它的数之间差值就上升了1倍。例如:设A = 00 * 2^-3 = 1.00 * 2^-3设B = 11 * 2^-4 = 1.11 * 2^-4
A与B两个数相邻,差值为0.01 * 2^-4 = 2^-6
设C = 01 * 2^-3 = 1.01 * 2^-3
C与A两个数相邻,差值为0.01 * 2^-3 = 2^-5
A前后,相邻两个数的差值为2倍。
这个问题对于非规格数也同样存在。貌似指数只要存在,这个问题就不可避免。
欢迎探讨。
Regards,
Junhao Li
edwin.jh.lee@gmail.com
---
From http://blog.csdn.net/qq_21311279/article/details/39583075