且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java double取值范围及Double的MAX_VALUE和MIN_VALUE

更新时间:2022-06-22 15:33:09

项目需要用一个特殊标识来表示用户未输入值,值类型为double,一般方案如下:
方案A: 使用double的最大值或者最小值;
方案B: 正无穷、负无穷、NaN(考虑到数值要保存数据库,所以就放弃了);
方案C: 改用包装类Double,null表示用户未输入(使用的是JdbcTemplate, 当从数据库取出的值为null时,getDouble会返回0而不是null)。

于是,初步决定使用方案A,深入之后,发现更大的问题,Java Double类中定义的最大值和最小值远超64位所能表示的范围,JDK中Double 定义的部分常量值如下:

public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324    
public static final double POSITIVE_INFINITY = 1.0 / 0.0;
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
public static final double NaN = 0.0d / 0.0;

懵B良久之后,在http://www.apihome.cn/api/java/Double.html找到了答案。

根据 IEEE 754 浮点“双精度格式”位布局,返回指定浮点值的表示形式,并保留 NaN 值。 第 63 位(掩码
0x8000000000000000L 选定的位)表示浮点数的符号。第 62-52 位(掩码 0x7ff0000000000000L
选定的位)表示指数。第 51-0 位(掩码 0x000fffffffffffffL 选定的位)表示浮点数的有效数字(有时也称为尾数)。

Java double的表示范围不是-2^63--(2^63)-1,同理float。以double为例,最高位为符号位,62-52位为指数位,51-0位为尾数,或者称有效数字位。

Java double取值范围及Double的MAX_VALUE和MIN_VALUE
注:图片引自《***》

由此可见double(同理,float也是)在计算机中的表示方式和int、long等不同,因此它才可以表示的如此大范围的数。顺带提一句,Double里的最小值是非0非负的最小值,需要最小值只需 -MAX_VALUE即可,负的最大值是-MIN_VALUE。

回到选什么样的方案来解决问题,最大值和最小值似乎可以,但是如此之大的数据保存到数据库也是一个及其复杂的问题,于是我们商议选择一个特殊的值(-123456789)来表示用户未输入。

其实,方案C是一个很好的方案,即使用Double来表示,但是需要做一些改变,如果getDouble方法获取到的值是0时,那就需要用getString方法来校验数据库值,若为null,则Double为null;若不为null,则表示用户确实设置的是0。

本着学习和分享的态度,买一送一,再来个知识点。
Java double取值范围及Double的MAX_VALUE和MIN_VALUE
注:图片中内容摘自《Java编程思想》