浮点数

Java虚拟机在任何浮点数操作中均不抛出异常. 特殊值(例如正无穷大,负无穷大或者NaN)作为可疑操作(比如除0)的结果返回. 指数位全为1, 表示特殊的浮点值. 指数位全为1而且尾数全为0,表示无穷大. 无穷大的符号由符号位表示出来.指数位全为1,尾数位不全为0, 表示该数为NaN. Java虚拟机总是为NaN产生同样的尾数:除了尾数中最高有效位为1外,其余各位均为0. float类型的这些特殊值如下所示:

值 浮点位(符号 指数 尾数)

+无穷 0 11111111 0000000000000000000000

-无穷 1 11111111 0000000000000000000000

NaN 1 11111111 1000000000000000000000

如果指数位既不全为0,又不全为1, 该数即为规范化的浮点数. 可以通过把指数位看作是一个正数, 然后从这个正数中减去一个偏移量的方法来确定2的幂指数. 对于float类型, 偏移量为127. 对于double类型, 偏移量为1023. 例如, 一个浮点数的指数区域为00000001, 那么它的幂指数可以通过如下步骤得到: 把指数区域看作是一个正整数(1), 然后减去偏移量(127), 然后就可以得到2的幂指数为1-127=-126. 这个值是float类型的的2的幂指数的最小值. 另外,指数区域为11111110的2的幂指数为(254-127),即为127. 127是float类型的最大的2的幂指数.

指数位全为0表示尾数非规范化, 这意味着未指明的最重要位的值为0,而不是1. 此时2的幂指数与规范化尾数的2的幂指数最小值相等. 对于float类型, 该值为-126. 与2的-126次幂相乘的规范化尾数, 其指数区域为00000001;而与2的-126次幂相乘的非规范化尾数,其指数区域为00000000.

指数范围底端的非规范化浮点数允许渐进的下溢. 如果这个最小的指数用来描述规范化数,那么一些较大的数将会下溢至0. 换句话说, 指定了非规范化数最小指数使得描述一些更小的数成为可能. 这些更小的数与那些规范化数相比较, 它们的精度较低, 但是这样可以有效地解决指数一旦达到规范化最小值,就会下溢至0的问题.

三、其他

所有浮点数取余操作都不会导致异常抛出. 任何值除以0的取余操作都会得出NaN的结果. 关于无穷大, 0, NaN和有限值之间的多种组合的取余结果如下所示:

 

a b a/b a%b

有限值 +-0.0 +-无限值 NaN

有限值 +=无限值 +-0 a

+-0.0 +-0.0 NaN NaN

+-无限值 有限值 +-无限值 NaN

+-无限值 +无限值 NaN NaN

四、参考(Float中的关于浮点数的处理)

 演示了从4个字节的数据中还原一个float

float bytesToFloat(byte[] bytes) {

 // 用一个联合,实现浮点数float和int的共用体

 union {

        int i;

        float f;

    } u;

 

    /* do conversion */

 

    int ival =    ((bytes[srcpos + 0] & 0xFF) << 24) +

               ((bytes[srcpos + 1] & 0xFF) << 16) +

               ((bytes[srcpos + 2] & 0xFF) << 8) +

               ((bytes[srcpos + 3] & 0xFF) << 0);

    u.i = ival;

    return u.f;

}