包装类Float中为何有两个常量来表示最小值

1)问:包装类Float中为何有两个常量来表示最小值:MIN_VALUE和MIN_NORMAL数组

① MIN_VALUE:最小正非零值常量,是非规格化浮点数所能表示的最小值。值为 3.4E-45 的常量。编码

② MIN_NORMAL:最小正标准值常量,是规格化浮点数所能表示的最小值,即 2^-126。spa

能够看出,定义中“格式化”是MIN_VALUE和MIN_NORMAL ,不一样的关键因素。code

分析:orm

在计算机中浮点数是由符号,指数和尾数组成。对象

同一个数字能够有多种表达方式111.11能够表示为1.1111*10^2也能够表示为0.11111*10^3,计算机要进行计算处理就必需要有固定的表达方式,不然计算起来会很影响效率,所以须要规划范表示浮点数,规范化之后表示为±1.f×2E−127,f是尾数,E是指数,因为整数部分固定为1,因此能够省略。blog

以单精度为例,指数位为8位,尾数位为23位,因为整数部分1固定23位的尾数能够表示24位,因此能够得出结论:ci

一个int值从第一个1到最后一个1为止的位数超过24,则该值不能被float精确表示。form

由于指数部分为了表示负数,因此采用偏移值的编码方式,将8位255一分为二,[ 1,127 ) 是负数,[ 127, 254 ] 是正数,0和255有特殊用途。因此最小的正规化表示为2^-126也就是MIN_NORMAL。class

因为在指数运算中可能出现的浮点数对应的指数小于-126,致使没法进行规范化保存,若是按规范化去表示,可能致使一个非零值变为零值,为了解决这种问题,IEEE 标准中引入了非规范(Denormalized)浮点数。规定当浮点数的指数为容许的最小指数值,尾数没必要是规范化的,这样能够保存更小的尾数,MIN_VALUE为能保存到的最小的非零值,就是MIN_NORMAL*2-23,也就是尾数1右移23位。

2)问:double a = 1.0-0.9的结果不精确等于0.1,为何?

浮点数在计算机中进行加减运算时,须要通过零值检测、对阶操做、尾数求和、规格化操做等操做,精度可能丢失。

float和double只能用来作科学计算或者是工程计算。

NumberFormat类的format()方法可使用BigDecimal对象做为其参数,能够利用BigDecimal对超出16位有效数字的货币值,百分值,以及通常数值进行格式化控制。 

验证:

double a = 1.0-0.9;//0.09999999999999998
double b=1,c=1.0;
System.out.println(b==c);//true
double d=0.09999999999999998;//0.09999999999999998
double e=1/10;
System.out.println("e="+e);//0.0
//float f=0.09999999999999998;不兼容,失精度
float g=0.09999999999999998f;//0.1
System.out.println(new BigDecimal(0.1));//0.1000000000000000055511151231257827021181583404541015625
System.out.println(new BigDecimal("1").subtract(new BigDecimal("0.9")));//0.1
相关文章
相关标签/搜索