This time to look at Double
the source code, based jdk1.8.0_181.jdk version, if wrong, please contact noted.
Foreword
Double
It is the double
basic data type of packaging, and double
is IEEE 754
a standard double-precision 64bit floating point, specific IEEE 754
some of the information here is no longer the standard describes in detail, it is recommended to see my previous article [Java source code] Float this I have a general understanding of the logic of the substantially uniform. For decimal floating point in Java, double
it is the default type.
Double-precision (64 bit)
FIG continue using similar described,
- sign: the sign bit,
1
bit. 0 for positive, 1 for negative. - exponent: Exponent bits,
11
bits. Double precision exponent part is -1022 + 1023 1024 plus an offset, the size of the index value (the special value 0 and 2047) from 1 to 2046 - fraction: mantissa bits,
52
bits.
Class information
public final class Double extends Number implements Comparable<Double>
复制代码
Definition with the final
identification, representation is 不可继承的
, further inherits Number
class that implements Comparable
the interface
Attributes
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;
复制代码
POSITIVE_INFINITY
Represents positive infinity, value0x7ff0000000000000L
; standard definition exponent field are all 1, all 0 mantissa fieldNEGATIVE_INFINITY
Represents negative infinity, value0xfff0000000000000L
; standard definition exponent field are all 1, all 0 mantissa fieldNaN
AbbreviationNot-a-Number
, the standard is defined as the exponent field all 1, not all domains ending in 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
复制代码
MAX_VALUE
The maximum number of the statute is0x1.fffffffffffffP+1023
, here is a hexadecimal floating point representation, that is0x7fefffffffffffffL
, also(2 - Math.pow(2, -52) * Math.pow(2, 1023))
, the calculated value1.7976931348623157e+308
MIN_NORMAL
The minimum number of the statute is0x1.0p-1022
, here is a hexadecimal floating point representation, that is0x0010000000000000L
, alsoMath.pow(2, -1022)
, the calculated value2.2250738585072014E-308
MIN_VALUE
The minimum number of non-statute0x0.0000000000001P-1022
, there is a hexadecimal floating point number, i.e.0x1L
, alsoMath.pow(2, -1074)
, the calculated value4.9e-324
public static final int MAX_EXPONENT = 1023;
public static final int MIN_EXPONENT = -1022;
复制代码
MAX_EXPONENT
It represents the maximum value of the index for 1023MIN_EXPONENT
It represents the minimum value of the index for-1022
public static final int SIZE = 64;
复制代码
It defines the bit
number of bits
public static final int BYTES = SIZE / Byte.SIZE;
复制代码
Defines the Double
object number of bytes is fixed at 8 calcd
@SuppressWarnings("unchecked")
public static final Class<Double> TYPE = (Class<Double>) Class.getPrimitiveClass("double");
复制代码
Acquires class information, Double.TYPE == double.class
the two are equivalent
private final double value;
复制代码
Double
Is a double
wrapper class, where the corresponding stored double
data values
private static final long serialVersionUID = -9172774392245257468L;
复制代码
method
Construction method
public Double(double value) {
this.value = value;
}
public Double(String s) throws NumberFormatException {
value = parseDouble(s);
}
复制代码
Can pass double
or String
a type parameter, String
the internal argument constructor call to parseDouble
a method for processing.
parseDouble method
public static double parseDouble(String s) throws NumberFormatException {
return FloatingDecimal.parseDouble(s);
}
复制代码
Internal calls FloatingDecimal.parseDouble
achieve specific logic, wherein the specific processes and Float
the like, can be viewed parsefloat methods appreciated described will not be repeated here. Return result corresponding to double
the type of data values.
toString method
public static String toString(double d) {
return FloatingDecimal.toJavaFormatString(d);
}
复制代码
Still we call FloatingDecimal.toJavaFormatString
a method, and the process Float
is basically the same, the result returns a corresponding string format.
toHexString method
public static String toHexString(double d) {
// 判断是否是有限数值
if (!isFinite(d) )
// 对于 infinity 和 NaN, 直接调用 toString 返回
return Double.toString(d);
else {
// 使用最大输出长度初始化StringBuilder容量
StringBuilder answer = new StringBuilder(24);
// 负数,增加符号标识
if (Math.copySign(1.0, d) == -1.0)
answer.append("-");
answer.append("0x");
d = Math.abs(d);
// 如果是0.0,直接输出返回
if(d == 0.0) {
answer.append("0.0p0");
} else {
// 判断是否为非规约数
boolean subnormal = (d < DoubleConsts.MIN_NORMAL);
// DoubleConsts.SIGNIF_BIT_MASK = 0x000FFFFFFFFFFFFFL
// & 操作保留尾数位数据
// | 操作是将最高位设为1,为了保留指数位的0,保留原来的长度,因为是个long类型整数
long signifBits = (Double.doubleToLongBits(d)
& DoubleConsts.SIGNIF_BIT_MASK) |
0x1000000000000000L;
// 规约数为1.开头,非规约数为0.开头
answer.append(subnormal ? "0." : "1.");
// 使用Long.toHexString获取十六进制字符串,提取尾数位对应的字符串信息
// 判断如果全为0,使用一个0替换
// 如若不是,去除字符串尾部的所有0
String signif = Long.toHexString(signifBits).substring(3,16);
answer.append(signif.equals("0000000000000") ? // 13 zeros
"0":
signif.replaceFirst("0{1,12}$", ""));
answer.append('p');
// DoubleConsts.MIN_EXPONENT = -1022
// 如果是非规约数,使用最小的指数位替换
// 规约数,获取对应的指数值替代
answer.append(subnormal ?
DoubleConsts.MIN_EXPONENT:
Math.getExponent(d));
}
return answer.toString();
}
}
复制代码
Overall logic in the code comments have been described, clear and simple, results are returned corresponding hexadecimal string.
valueOf Method
public static Double valueOf(double d) {
return new Double(d);
}
public static Double valueOf(String s) throws NumberFormatException {
return new Double(parseDouble(s));
}
复制代码
There are two valueOf
methods, when the parameter is double
time type, direct new Double(d)
and return; string argument for calling parseDouble
is converted into double
a data value, then a new new object is returned.
isNaN method
public static boolean isNaN(double v) {
return (v != v);
}
public boolean isNaN() {
return isNaN(value);
}
复制代码
Determining whether the NaN
use (v != v)
is determined; specific NaN
rules can be described with reference isNaN Method
isInfinite way
public static boolean isInfinite(double v) {
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
public boolean isInfinite() {
return isInfinite(value);
}
复制代码
Judgment is not infinity, contains positive and negative infinity
isFinite method
public static boolean isFinite(double d) {
return Math.abs(d) <= DoubleConsts.MAX_VALUE;
}
复制代码
Whether the absolute value of the input parameter by less than double
a maximum value of the type, the number of judgment is not limited
xxxValue method
public byte byteValue() {
return (byte)value;
}
public short shortValue() {
return (short)value;
}
public int intValue() {
return (int)value;
}
public long longValue() {
return (long)value;
}
public float floatValue() {
return (float)value;
}
public double doubleValue() {
return value;
}
复制代码
Corresponding to the type of the return value, directly cast
hashCode method
@Override
public int hashCode() {
return Double.hashCode(value);
}
public static int hashCode(double value) {
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
复制代码
>>>
Unsigned right shift, high filled to 0. (bits ^ (bits >>> 32))
32 is a logic high and low 32-bit XOR returns int
integer value hashCode
longBitsToDouble method
public static native double longBitsToDouble(long bits);
复制代码
longBitsToDouble
It is a native
method, implemented by code c. Returns the corresponding double
data value
-
Parameters
0x7ff0000000000000L
, the result is positive infinity -
Parameters
0xfff0000000000000L
, the result is negative infinity -
Parameters
0x7ff0000000000001L ~ 0x7fffffffffffffffL
or0xfff0000000000001L ~ 0xffffffffffffffffL
the time between, the result isNaN
.
doubleToRawLongBits 方法
public static native long doubleToRawLongBits(double value);
复制代码
doubleToRawLongBits
It is a native
method, implemented by the corresponding code c.
Results retention NaN
values, the result is positive infinity 0x7ff0000000000000L
; the result is negative infinity 0xfff0000000000000L
; when the parameter is NaN
, the actual result will be an input parameter corresponding to an integer value, as does the method doubleToLongBits
of NaN
uniformly processing the return value
doubleToLongBits 方法
public static long doubleToLongBits(double value) {
long result = doubleToRawLongBits(value);
if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
DoubleConsts.EXP_BIT_MASK) &&
(result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
result = 0x7ff8000000000000L;
return result;
}
复制代码
Substantially the doubleToRawLongBits
same method, except for increasing the NaN
determination. If NaN
the direct return 0x7ff8000000000000L
( for all NaN
values of a unified return value processing ). Here recognition NaN
logic meet exponent field are all 1, all 0 mantissa field standards, as described in reference may floatToIntBits methods described.
equals method
public boolean equals(Object obj) {
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
}
复制代码
First, judgment is not Double
the object instance, and by doubleToLongBits
obtaining the corresponding two long integers, determines whether they match; It is noted that some special value determination logic.
System.out.println(new Double(0.0d).equals(new Double(-0.0d))); // false
System.out.println(new Double(Double.NaN).equals(new Double(-Double.NaN))); // true
复制代码
compare method
public int compareTo(Double anotherDouble) {
return Double.compare(value, anotherDouble.value);
}
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)
}
复制代码
And Float
consistent, can refer to compare methods in the paragraphs that need attention is still -0.0
, 0.0
, Double.NaN
and -Double.NaN
a special kind of value, you can write your own conduct several test.
sum, min, max method
public static double sum(double a, double b) {
return a + b;
}
public static double max(double a, double b) {
return Math.max(a, b);
}
public static double min(double a, double b) {
return Math.min(a, b);
}
复制代码
The logic is simple, it's still important to note that -0.0
, 0.0
, Double.NaN
and -Double.NaN
a special kind of value, you can test yourself at the results, might surprise you, oh.
Special Note
Because double
is 64bit, need to pay attention to the next double
atom logic, here is the official document specifying Non-Atomic Treatment of double
andlong
, references explain:
For the purposes of the Java programming language memory model, a single write to a non-volatile
long
ordouble
value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a thread sees the first 32 bits of a 64-bit value from one write, and the second 32 bits from another write.Writes and reads of volatile
long
anddouble
values are always atomic.Writes to and reads of references are always atomic, regardless of whether they are implemented as 32-bit or 64-bit values.
Some implementations may find it convenient to divide a single write action on a 64-bit
long
ordouble
value into two write actions on adjacent 32-bit values. For efficiency's sake, this behavior is implementation-specific; an implementation of the Java Virtual Machine is free to perform writes tolong
anddouble
values atomically or in two parts.Implementations of the Java Virtual Machine are encouraged to avoid splitting 64-bit values where possible. Programmers are encouraged to declare shared 64-bit values as
volatile
or synchronize their programs correctly to avoid possible complications.
For reasons of the Java programming language memory model, for no volatile
modification long
or double
a single write operation, a write operation can be divided into two, each of the 32 operations. Which can result in false results thread to read 32-bit data from different combinations of thread writes.
For volatile
modified long
and double
, the write and read operations are atomic.
For write references, or whether it is 32-bit data value of 64, it is atomic.
Some implementations may find a single write data into two 64-bit writes the 32-bit data of neighboring easy. For the sake of efficiency, which is more particular implementation; the JVM implementations selection of free long
and value
writing atomic logic or two steps.
Encourage JVM implementation to avoid splitting logic 64 in possible. For programmers, encourage value added to the 64-bit shared volatile
or synchronize
statement modified to avoid complex problems.
Can be seen from the above description, the atomicity problem may exist. But for now when most of the 64 machines and 64-bit JVM, the problem is generally ignored. But when you use the environment does not meet the requirements, please pay attention to the existence of this problem .
to sum up
The total code logic, Double
and Float
logic are basically the same, as are IEEE 754
the number of different bit floating-point standard, mainly used to bring some gaps. If you already know float
, then I understand that this is actually very simple.
At last
Blog Original Address: blog.renyijiu.com/post/java source ...