Double源碼分析
- 一.概述
- 二.源碼分析
- 1.全局變量
- 2.構造方法
- 3. parseDouble方法
- 4. valueOf方法
- 5. isNaN方法
- 6. isInfinite方法
- 7. isFinite方法
- 8. doubleToLongBits方法
- 9. longBitsToDouble方法
- 10. toString方法
- 11. toHexString方法
- 12. byteValue方法
- 13. shortValue方法
- 14. intValue方法
- 15. longValue方法
- 16. floatValue方法
- 17. doubleValue方法
- 18. hashCode方法
- 19. equals方法
- 20. compareTo方法
- 21. sum方法
- 22. max方法
- 23. min方法
一.概述
Double是double的包裝類,用於表示雙精度浮點數。
Double的表示方法和int、short、long不同。Double滿足IEEE754浮點數表示法。
Double表示的數值佔8個字節,共64位。其中0到51位表示尾數部分;52到63位表示指數部分;64位爲符號位。
Double.java中的相關代碼:
public final class Double extends Number implements Comparable<Double> {
…
}
1.Double被final修飾,不能被繼承。
2.繼承了Number,可以實現數值間的轉換。
3.實現了Comparable<Double>接口,可以進行Double類型對象之間的比較。
二.源碼分析
1.全局變量
Double.java中的相關代碼:
// 表示正無窮
// 它的值和Double.longBitsToDouble(0x7ff0000000000000L)計算的結果相同
public static final double POSITIVE_INFINITY = 1.0 / 0.0;
// 表示負無窮
// 它的值和Double.longBitsToDouble(0xfff0000000000000L)計算的結果相同
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
// 表示不是一個數,即一個數不能被表示
// 它的值和Double.longBitsToDouble(0x7ff8000000000000L)計算的結果相同
public static final double NaN = 0.0d / 0.0;
// 表示double所能表示的最大值:1.7976931348623157e+308
// 它的值和Double.longBitsToDouble(0x7fefffffffffffffL)計算的結果相同
public static final double MAX_VALUE = 0x1.fffffffffffffP+1023;
// 表示正常情況下,double可以表示的最小正數:2.2250738585072014E-308
// 正常情況爲小數點前爲0x1
// 它的值和Double.longBitsToDouble(0x0010000000000000L)計算的結果相同
public static final double MIN_NORMAL = 0x1.0p-1022;
// 表示double實際上可以表示的最小非零正數:4.9e-324
// 小數點前爲0x0
// 它的值和Double.longBitsToDouble(0x1L)計算的結果相同
public static final double MIN_VALUE = 0x0.0000000000001P-1022;
// double可以表示的最大指數
public static final int MAX_EXPONENT = 1023;
// double可以表示的最小指數
public static final int MIN_EXPONENT = -1022;
// double佔的位數
public static final int SIZE = 64;
// 一個double數值佔的字節數
public static final int BYTES = SIZE / Byte.SIZE;
// 抑制沒有類型檢查而出現的警告
@SuppressWarnings("unchecked")
// Double類中對應的原始的double
// Double.class和double.class不相等,但Double.TYPE和double.class相等
public static final Class<Double> TYPE = (Class<Double>) Class.getPrimitiveClass("double");
// 用於存儲double的數值
private final double value;
// 用於序列化
private static final long serialVersionUID = -9172774392245257468L;
2.構造方法
1)參數爲double
Double.java中的相關代碼:
public Double(double value) {
// 保存到全局變量
this.value = value;
}
2)參數爲String
Double.java中的相關代碼:
public Double(String s) throws NumberFormatException {
// 調用parseDouble方法,將字符串解析成double型數值
value = parseDouble(s);
}
3. parseDouble方法
將字符串解析成double型數值。
Double.java中的相關代碼:
public static double parseDouble(String s) throws NumberFormatException {
// 調用FloatingDecimal的parseDouble方法
return FloatingDecimal.parseDouble(s);
}
4. valueOf方法
1)參數爲double
將double型數值轉換爲Double對象。
Double.java中的相關代碼:
public static Double valueOf(double d) {
// 創建Double對象,對double數值進行封裝,返回
return new Double(d);
}
2)參數爲String
將String對象轉換爲Double對象。
Double.java中的相關代碼:
public static Double valueOf(String s) throws NumberFormatException {
// 調用parseDouble方法,將字符串解析成double型數值
// 創建Double對象,對double數值進行封裝,返回
return new Double(parseDouble(s));
}
5. isNaN方法
判斷當前的數是不是數值型的數。
Double.java中的相關代碼:
public boolean isNaN() {
// 調用了重載方法
return isNaN(value);
}
調用重載的isNaN方法。
判斷double型的數是不是數值型的數。
Double.java中的相關代碼:
public static boolean isNaN(double v) {
// 每個NaN的存儲地址不同
return (v != v);
}
6. isInfinite方法
判斷當前的數是不是無窮大。
Double.java中的相關代碼:
public boolean isInfinite() {
// 調用了重載方法
return isInfinite(value);
}
調用了重載的isInfinite方法。
判斷double型的數是不是無窮大。
Double.java中的相關代碼:
public static boolean isInfinite(double v) {
// 判斷是否爲正無窮或負無窮
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
7. isFinite方法
判斷一個double型的數是否有限。
Double.java中的相關代碼:
public static boolean isFinite(double d) {
// 對double數取絕對值,判斷是否小於等於double能表示的最大值
return Math.abs(d) <= DoubleConsts.MAX_VALUE;
}
8. doubleToLongBits方法
將double型的數轉換成滿足IEEE 754浮點型表示法的long型的數。
符號位MASK:0x8000000000000000L
指數位MASK:0x7ff0000000000000L
有效位MASK:0x000fffffffffffffL
正無窮:0x7ff0000000000000L
負無窮:0xfff0000000000000L
NaN:0x7ff8000000000000L
Double.java中的相關代碼:
public static long doubleToLongBits(double value) {
// 調用doubleToRawLongBits轉換成long型的數
// 詳解在1)處
long result = doubleToRawLongBits(value);
// 根據指數位和非零有效位判斷是不是NaN
if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
DoubleConsts.EXP_BIT_MASK) &&
(result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
// 若是,則設置爲NaN
result = 0x7ff8000000000000L;
// 返回
return result;
}
1)doubleToRawLongBits方法
Double.java中的相關代碼:
public static native long doubleToRawLongBits(double value);
該方法是一個native方法,該方法會將一個double型的數轉換成滿足IEEE 754浮點型表示法的long型的數,即使該數爲NaN,也會進行轉換。
9. longBitsToDouble方法
將long型的數按照IEEE 754浮點數標準轉換爲double型的數。
Double.java中的相關代碼:
public static native double longBitsToDouble(long bits);
該方法是一個native方法。
10. toString方法
將Double對象轉換爲String對象。
Double.java中的相關代碼:
public String toString() {
// 調用了重載方法
return toString(value);
}
調用了重載的toString方法。
Double.java中的相關代碼:
public static String toString(double d) {
// 調用FloatingDecimal的toJavaFormatString方法
return FloatingDecimal.toJavaFormatString(d);
}
11. toHexString方法
將double型的數轉換爲十六進制的String對象。
Double.java中的相關代碼:
public static String toHexString(double d) {
// 若該數不是有限的,即超過了double型的最大值或者爲NaN
if (!isFinite(d) )
// 調用toString方法進行轉換
return Double.toString(d);
else { // 若該數有限
// 用來保存轉換的十六進制的字符串
StringBuilder answer = new StringBuilder(24);
// 若爲負數
if (Math.copySign(1.0, d) == -1.0)
// 拼接一個負號
answer.append("-");
// 拼接16進制的標識符
answer.append("0x");
// 求絕對值
d = Math.abs(d);
// 若數值爲0
if(d == 0.0) {
// 則拼接“0.0p0”,即0乘以2的0次方,爲0
answer.append("0.0p0");
} else { // 若不爲零
// 判斷數值是否超過了正常的最小正數
boolean subnormal = (d < DoubleConsts.MIN_NORMAL);
// 調用doubleToLongBits方法
// 將其轉換成滿足IEEE 754浮點型標準的long型數
// 進行與運算,64到52位變爲0
// 提取51到0位,即有效位(尾數部分)
// 最後進行或運算,最高位,即64位,置爲1
long signifBits = (Double.doubleToLongBits(d)
& DoubleConsts.SIGNIF_BIT_MASK) |
0x1000000000000000L;
// 若數值小於正常的最小正數
// 則拼接”0.”,即0x0.
// 否則,拼接”1.”,即0x1.
answer.append(subnormal ? "0." : "1.");
// 調用Long的toHexString方法
// 將有效位轉換爲16進製表示的字符串,截取從第三位到第十六位
// 64位二進制轉換位十六進制爲16位(0到15)
// 十六位中,前三位(0,1,2)表示符號位和指數部分
// 有效位從第四位(3)開始
String signif = Long.toHexString(signifBits).substring(3,16);
// 若有效位都是0,則直接拼接一個”0”
// 若不全爲0,則進行正則表達式匹配
// 從後向前,去掉最少一個最多12個的”0”
answer.append(signif.equals("0000000000000") ?
"0":
signif.replaceFirst("0{1,12}$", ""));
// 拼接p,表示指數中以2爲底數
answer.append('p');
// 若數值小於正常的最小正數
// 則指數部分拼接最小指數
// 否則,調用Math的getExponent方法獲取指數,再拼接
answer.append(subnormal ?
DoubleConsts.MIN_EXPONENT:
Math.getExponent(d));
}
// 獲取字符串,返回
return answer.toString();
}
}
12. byteValue方法
獲取當前數值對應的byte型數。
Double.java中的相關代碼:
public byte byteValue() {
// 進行類型轉換,返回
return (byte)value;
}
13. shortValue方法
獲取當前數值對應的short型數。
Double.java中的相關代碼:
public short shortValue() {
// 進行類型轉換,返回
return (short)value;
}
14. intValue方法
獲取當前數值對應的int型數。
Double.java中的相關代碼:
public int intValue() {
// 進行類型轉換,返回
return (int)value;
}
15. longValue方法
獲取當前數值對應的long型數。
Double.java中的相關代碼:
public long longValue() {
// 進行類型轉換,返回
return (long)value;
}
16. floatValue方法
獲取當前數值對應的float型數。
Double.java中的相關代碼:
public float floatValue() {
// 進行類型轉換,返回
return (float)value;
}
17. doubleValue方法
獲取當前數值對應的double型數。
Double.java中的相關代碼:
public double doubleValue() {
// 直接返回
return value;
}
18. hashCode方法
獲取Double對象的哈希值。
Double.java中的相關代碼:
@Override
public int hashCode() {
// 調用Double的靜態方法
return Double.hashCode(value);
}
1)hashCode方法
Double.java中的相關代碼:
public static int hashCode(double value) {
// 將value轉換成滿足IEEE 754浮點型標準的long型數
long bits = doubleToLongBits(value);
// 將其不帶符號右移32位,再和原數進行異或運算
// 最後進行類型轉換,返回
return (int)(bits ^ (bits >>> 32));
}
19. equals方法
比較兩個Double對象是否相等。
Double.java中的相關代碼:
public boolean equals(Object obj) {
// 若類型爲Double
// 同時轉換爲long型後比較相等,則返回true
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
}
20. compareTo方法
對兩個Double對象進行比較。
若相等,則返回0。若大於anotherDouble則返回1,小於則返回-1。
Double.java中的相關代碼:
public int compareTo(Double anotherDouble) {
// 調用Double的靜態方法compare
return Double.compare(value, anotherDouble.value);
}
1)compare方法
Double.java中的相關代碼:
public static int compare(double d1, double d2) {
// 若小於,則返回-1
if (d1 < d2)
return -1;
// 若大於,則返回1
if (d1 > d2)
return 1;
// 此時兩個數可能相等,或至少其中一個爲NaN
// 調用doubleToLongBits方法進行轉換
long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);
// 若相等,則返回0
// 若小於,說明thisBits =-0.0, anotherBits = 0.0)
// 或thisBits != NaN, anotherBits = NaN
// 若大於,說明thisBits =0.0, anotherBits = -0.0)
// 或thisBits = NaN, anotherBits != NaN
return (thisBits == anotherBits ? 0 :
(thisBits < anotherBits ? -1 :
1));
}
21. sum方法
求兩個double數的和
Double.java中的相關代碼:
public static double sum(double a, double b) {
// 相加,返回
return a + b;
}
22. max方法
求兩個double數的最大值。
Double.java中的相關代碼:
public static double max(double a, double b) {
// 調用Math的max方法
return Math.max(a, b);
}
23. min方法
求兩個double數的最小值。
Double.java中的相關代碼:
public static double min(double a, double b) {
// 調用Math的min方法
return Math.min(a, b);
}