java源码分析---Double类(JDK14)
Double
Double 类将基本类型 double 的值包装在对象中。 Double 类型的对象包含一个类型为 double 的属性。
另外,提供了几种将 double 转换为 String 和 String 转换为 double 的方法,以及其他在处理 double 类型时有用的方法。
Double 类被 final 关键字修饰,不能被继承。Double 类继承自 Number 类,实现了 Comparable 、 Constable 、 ConstantDesc 接口。
public final class Double extends Number implements Comparable<Double>, Constable, ConstantDesc {
private final double value;
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;
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 int MAX_EXPONENT = 1023;
public static final int MIN_EXPONENT = -1022;
public static final int SIZE = 64;
public static final int BYTES = SIZE / Byte.SIZE;
public static final Class<Double> TYPE = (Class<Double>) Class.getPrimitiveClass("double");
}
value 为常量,用于保存 Double 对象所对应的基本类型 double 的值。
POSITIVE_INFINITY 为常量,表示正无穷。
NEGATIVE_INFINITY 为常量,表示负无穷。
NAN 为常量,表示值为 double 类型的非数字值。
MAX_VALUE 为常量,表示 double 类型的值所能表示的最大正数。(2-2-52)·21023
MIN_NORMAL 为常量,表示 double 类型标准浮点数的最小正数。2-1022
MIN_VALUE 为常量,表示 double 类型的值所能表示的最小正数。2-1074
MAX_EXPONENT 为常量,表示有限双精度变量可能具有的最大指数。
MIN_EXPONENT 为常量,表示归一化双精度变量可能具有的最小指数。
SIZE 为静态常量,用于表示二进制形式的 double 类型所需要的位数。
BYTES 为静态常量,用于表示二进制形式的 double 值所占的字节数。即8个字节。
TYPE 为静态常量,基本类型 double 的 Class 对象。
toString(double)
返回 double 参数的字符串表示形式。
- 如果参数为NaN,则结果为字符串“ NaN”。
- 否则,结果是一个字符串,代表参数的符号和大小(绝对值)。如果符号为负,则结果的第一个字符为’-’(’\ u002D’);如果符号为正,则结果中不显示符号字符。至于大小m:
- 如果m为无穷大,则用字符“ Infinity”表示;因此,正无穷大产生结果“无穷大”,而负无穷大产生结果“-无穷大”。
- 如果m为零,则用字符“ 0.0”表示;因此,负零产生结果“ -0.0”,而正零产生结果“ 0.0”。
public static String toString(double d) {
return FloatingDecimal.toJavaFormatString(d);
}
toString()
将该对象的值以字符串形式返回。
public String toString() {
return toString(value);
}
toHexString(double)
返回double参数的十六进制字符串表示形式。
public static String toHexString(double d) {
/*
* Modeled after the "a" conversion specifier in C99, section
* 7.19.6.1; however, the output of this method is more
* tightly specified.
*/
if (!isFinite(d) )
// For infinity and NaN, use the decimal output.
return Double.toString(d);
else {
// Initialized to maximum size of output.
StringBuilder answer = new StringBuilder(24);
if (Math.copySign(1.0, d) == -1.0) // value is negative,
answer.append("-"); // so append sign info
answer.append("0x");
d = Math.abs(d);
if(d == 0.0) {
answer.append("0.0p0");
} else {
boolean subnormal = (d < Double.MIN_NORMAL);
// Isolate significand bits and OR in a high-order bit
// so that the string representation has a known
// length.
long signifBits = (Double.doubleToLongBits(d)
& DoubleConsts.SIGNIF_BIT_MASK) |
0x1000000000000000L;
// Subnormal values have a 0 implicit bit; normal
// values have a 1 implicit bit.
answer.append(subnormal ? "0." : "1.");
// Isolate the low-order 13 digits of the hex
// representation. If all the digits are zero,
// replace with a single 0; otherwise, remove all
// trailing zeros.
String signif = Long.toHexString(signifBits).substring(3,16);
answer.append(signif.equals("0000000000000") ? // 13 zeros
"0":
signif.replaceFirst("0{1,12}$", ""));
answer.append('p');
// If the value is subnormal, use the E_min exponent
// value for double; otherwise, extract and report d's
// exponent (the representation of a subnormal uses
// E_min -1).
answer.append(subnormal ?
Double.MIN_EXPONENT:
Math.getExponent(d));
}
return answer.toString();
}
}
-
如果是浮点数 d 无穷大或者NaN,则直接调用 toString(double) 函数。
-
浮点数 d 的绝对值是否小于 MAX_VALUE,则先初始化字符串最大长度为 24。
-
先判断浮点数 d 是否为负数,如果是负数,需要在字符串最前面加上负号。
-
在字符串中加入 “ 0x” ,表示为16进制表示形式。
-
取浮点数 d 的绝对值,如果 d 的值等于0.0,则在字符串中加入“0.0p0”。
-
调用 doubleToLongBits(double) 方法将浮点数 d 转换成十六进制bit位表示形式,和 SIGNIF_BIT_MASK 进行 与 操作,结果即尾数。然后进行 或 操作,将符号位置为1。
public static final long SIGNIF_BIT_MASK = 0x000FFFFFFFFFFFFFL;
-
如果浮点数 d 小于最大标准数,则将“0.”加入字符串,否则,加入“1.”。
-
将刚计算的尾数 signifBits 通过 Long.toHexString(long) 方法转为字符串,只截取其中3-16位尾数部分。(请点击查看 Long 类的源码分析,查看关于 Long.toHexString(long) 方法的详解)
-
如果尾数有多个零,则只保留一个0,这里通过正则表达式匹配(此处含义为从最后面开始匹配,0的个数最少为1个,最多为12个),调用 String.replaceFirst() 方法将指定位置的元素替换。(点击查看 String 类的源码分析了解该方法详情)关于正则表达式点此了解详情
-
然后在字符串中加入指数信息,通过 Math.getExponent(double) 方法获取浮点数 d 的指数。
isFinite(double)
如果该浮点数的绝对值小于浮点数最大值 MAX_VALUE ,则返回true,否则,返回false(无穷大或者NaN)。
public static boolean isFinite(double d) {
return Math.abs(d) <= Double.MAX_VALUE;
}
doubleToLongBits(double)
根据[IEEE 754浮点数标准]([https://baike.baidu.com/item/IEEE%20754/3869922?fr=aladdin](https://baike.baidu.com/item/IEEE 754/3869922?fr=aladdin)),返回指定浮点值的表示形式。(不了解该标准的可以点击链接了解详情)
位63表示浮点数的符号。位62-52表示指数。位51-0表示浮点数的有效位(有时称为尾数)。
如果参数为正无穷大,则结果为0x7ff0000000000000L。
如果参数为负无穷大,则结果为0xfff0000000000000L。
如果参数为NaN,则结果为0x7ff8000000000000L。
public static long doubleToLongBits(double value) {
if (!isNaN(value)) {
return doubleToRawLongBits(value);
}
return 0x7ff8000000000000L;
}
doubleToRawLongBits(double)
本地静态方法,doubleToLongBits(double) 方法的具体实现,具体功能一致。该方法在本地采用C/C++实现。
public static native long doubleToRawLongBits(double value);
valueOf(double)
将 double 类型的值转为 Double 对象。
public static Double valueOf(double d) {
return new Double(d);
}
valueOf(String)
将字符串 s 转为 Double 对象。
调用 parseDouble(String) 方法先将字符串 s 转为 double 类型,然后调用 Double 类的构造方法实现。
public static Double valueOf(String s) throws NumberFormatException {
return new Double(parseDouble(s));
}
parseDouble(String)
将字符串 s 转换为 double 类型的值。 调用 FloatingDecimal.parseDouble(String) 方法实现。
public static double parseDouble(String s) throws NumberFormatException {
return FloatingDecimal.parseDouble(s);
}
isNaN(double)
如果浮点数 v 是NaN,则返回true,否则,返回false。
public static boolean isNaN(double v) {
return (v != v);
}
isNaN()
如果该对象的值是否是 NaN,则返回true,否则,返回false。
public boolean isNaN() {
return isNaN(value);
}
isInfinite(double)
如果浮点数 v 是无穷,则返回true,否则,返回false。
public static boolean isInfinite(double v) {
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
isInfinite()
如果该对象的值是无穷,则返回true,否则,返回false。
public boolean isInfinite() {
return isInfinite(value);
}
byteValue() 、shortValue() 、 intValue() 、 longValue 、 floatValue() 、 doubleValue() 等方法实现简单,不再赘述。
hashCode(double)
返回浮点数 value 的哈希值。将 value 数据按 bit 转为16进制,逻辑右移32为后再与自身求异或。转为 int 形式即为哈希值。(即将高32位于低32位求异或)
public static int hashCode(double value) {
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
equals(Object)
将此对象与指定对象进行比较。 当且仅当参数不为null且是一个 Double 对象,doubleToLongBitsdouble) 方法在应用于每个值时返回相同的 long 值时,才将两个 double 值视为相同。
如果d1和d2都表示 NaN ,则即使 NaN == NaN的值为false,equals方法也将返回true。
如果d1表示+0.0,而d2表示-0.0,反之亦然,即使+0.0 ==-0.0的值为true,相等测试的值为false。
public boolean equals(Object obj) {
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
}
longBitsToDouble(long)
本地静态方法,返回对应于给定位表示形式的double值。根据IEEE 754浮点“双格式”位布局,该参数被认为是浮点值的表示。
如果参数为0x7ff0000000000000L,则结果为正无穷大。
如果参数为0xfff0000000000000L,则结果为负无穷大。
如果参数是0x7ff0000000000001L到0x7fffffffffffffffffL或0xfff0000000000001L到0xffffffffffffffffL范围内的任何值,则结果为NaN。
Java提供的IEEE 754浮点运算无法区分具有不同位模式的相同类型的两个NaN值。 NaN的不同值只能通过使用 doubleToRawLongBits 方法来区分。
public static native double longBitsToDouble(long bits);
compare(double, double)
比较给定的两个浮点值的大小。
public static int compare(double d1, double d2) {
if (d1 < d2)
return -1; // Neither val is NaN, thisVal is smaller
if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger
// Cannot use doubleToRawLongBits because of possibility of NaNs.
long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
sum(double, double) 、 max(double, double) 、 min(double, double) 等方法实现简单,不再赘述。
describeConstable()
Constable 接口中的方法。点此了解详情。
@Override
public Optional<Double> describeConstable() {
return Optional.of(this);
}
resolveConstantDesc(MethodHandles.Lookup)
ConstantDesc 接口中的方法,点此了解详情。
@Override
public Double resolveConstantDesc(MethodHandles.Lookup lookup) {
return this;
}
本文地址:https://blog.csdn.net/wrz_1028/article/details/107699067
上一篇: jdk1.8特性总结
下一篇: SwiftUI 中创建反弹动画的实现