1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.lang;
19
20/**
21 * The wrapper for the primitive type {@code double}.
22 *
23 * @see java.lang.Number
24 * @since 1.0
25 */
26public final class Double extends Number implements Comparable<Double> {
27
28    private static final long serialVersionUID = -9172774392245257468L;
29
30    /**
31     * The value which the receiver represents.
32     */
33    private final double value;
34
35    /**
36     * Constant for the maximum {@code double} value, (2 - 2<sup>-52</sup>) *
37     * 2<sup>1023</sup>.
38     */
39    public static final double MAX_VALUE = 1.79769313486231570e+308;
40
41    /**
42     * Constant for the minimum {@code double} value, 2<sup>-1074</sup>.
43     */
44    public static final double MIN_VALUE = 5e-324;
45
46    /* 4.94065645841246544e-324 gets rounded to 9.88131e-324 */
47
48    /**
49     * Constant for the Not-a-Number (NaN) value of the {@code double} type.
50     */
51    public static final double NaN = 0.0 / 0.0;
52
53    /**
54     * Constant for the Positive Infinity value of the {@code double} type.
55     */
56    public static final double POSITIVE_INFINITY = 1.0 / 0.0;
57
58    /**
59     * Constant for the Negative Infinity value of the {@code double} type.
60     */
61    public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
62
63    /**
64     * The {@link Class} object that represents the primitive type {@code
65     * double}.
66     *
67     * @since 1.1
68     */
69    @SuppressWarnings("unchecked")
70    public static final Class<Double> TYPE
71            = (Class<Double>) double[].class.getComponentType();
72
73    // Note: This can't be set to "double.class", since *that* is
74    // defined to be "java.lang.Double.TYPE";
75
76    /**
77     * Constant for the number of bits needed to represent a {@code double} in
78     * two's complement form.
79     *
80     * @since 1.5
81     */
82    public static final int SIZE = 64;
83
84    /**
85     * Constructs a new {@code Double} with the specified primitive double
86     * value.
87     *
88     * @param value
89     *            the primitive double value to store in the new instance.
90     */
91    public Double(double value) {
92        this.value = value;
93    }
94
95    /**
96     * Constructs a new {@code Double} from the specified string.
97     *
98     * @param string
99     *            the string representation of a double value.
100     * @throws NumberFormatException
101     *             if {@code string} can not be decoded into a double value.
102     * @see #parseDouble(String)
103     */
104    public Double(String string) throws NumberFormatException {
105        this(parseDouble(string));
106    }
107
108    /**
109     * Compares this object to the specified double object to determine their
110     * relative order. There are two special cases:
111     * <ul>
112     * <li>{@code Double.NaN} is equal to {@code Double.NaN} and it is greater
113     * than any other double value, including {@code Double.POSITIVE_INFINITY};</li>
114     * <li>+0.0d is greater than -0.0d</li>
115     * </ul>
116     *
117     * @param object
118     *            the double object to compare this object to.
119     * @return a negative value if the value of this double is less than the
120     *         value of {@code object}; 0 if the value of this double and the
121     *         value of {@code object} are equal; a positive value if the value
122     *         of this double is greater than the value of {@code object}.
123     * @throws NullPointerException
124     *             if {@code object} is {@code null}.
125     * @see java.lang.Comparable
126     * @since 1.2
127     */
128    public int compareTo(Double object) {
129        return compare(value, object.value);
130    }
131
132    @Override
133    public byte byteValue() {
134        return (byte) value;
135    }
136
137    /**
138     * Converts the specified double value to a binary representation conforming
139     * to the IEEE 754 floating-point double precision bit layout. All
140     * <em>Not-a-Number (NaN)</em> values are converted to a single NaN
141     * representation ({@code 0x7ff8000000000000L}).
142     *
143     * @param value
144     *            the double value to convert.
145     * @return the IEEE 754 floating-point double precision representation of
146     *         {@code value}.
147     * @see #doubleToRawLongBits(double)
148     * @see #longBitsToDouble(long)
149     */
150    public static native long doubleToLongBits(double value);
151
152    /**
153     * Converts the specified double value to a binary representation conforming
154     * to the IEEE 754 floating-point double precision bit layout.
155     * <em>Not-a-Number (NaN)</em> values are preserved.
156     *
157     * @param value
158     *            the double value to convert.
159     * @return the IEEE 754 floating-point double precision representation of
160     *         {@code value}.
161     * @see #doubleToLongBits(double)
162     * @see #longBitsToDouble(long)
163     */
164    public static native long doubleToRawLongBits(double value);
165
166    /**
167     * Gets the primitive value of this double.
168     *
169     * @return this object's primitive value.
170     */
171    @Override
172    public double doubleValue() {
173        return value;
174    }
175
176    /**
177     * Tests this double for equality with {@code object}.
178     * To be equal, {@code object} must be an instance of {@code Double} and
179     * {@code doubleToLongBits} must give the same value for both objects.
180     *
181     * <p>Note that, unlike {@code ==}, {@code -0.0} and {@code +0.0} compare
182     * unequal, and {@code NaN}s compare equal by this method.
183     *
184     * @param object
185     *            the object to compare this double with.
186     * @return {@code true} if the specified object is equal to this
187     *         {@code Double}; {@code false} otherwise.
188     */
189    @Override
190    public boolean equals(Object object) {
191        return (object == this)
192                || (object instanceof Double)
193                && (doubleToLongBits(this.value) == doubleToLongBits(((Double) object).value));
194    }
195
196    @Override
197    public float floatValue() {
198        return (float) value;
199    }
200
201    @Override
202    public int hashCode() {
203        long v = doubleToLongBits(value);
204        return (int) (v ^ (v >>> 32));
205    }
206
207    @Override
208    public int intValue() {
209        return (int) value;
210    }
211
212    /**
213     * Indicates whether this object represents an infinite value.
214     *
215     * @return {@code true} if the value of this double is positive or negative
216     *         infinity; {@code false} otherwise.
217     */
218    public boolean isInfinite() {
219        return isInfinite(value);
220    }
221
222    /**
223     * Indicates whether the specified double represents an infinite value.
224     *
225     * @param d
226     *            the double to check.
227     * @return {@code true} if the value of {@code d} is positive or negative
228     *         infinity; {@code false} otherwise.
229     */
230    public static boolean isInfinite(double d) {
231        return (d == POSITIVE_INFINITY) || (d == NEGATIVE_INFINITY);
232    }
233
234    /**
235     * Indicates whether this object is a <em>Not-a-Number (NaN)</em> value.
236     *
237     * @return {@code true} if this double is <em>Not-a-Number</em>;
238     *         {@code false} if it is a (potentially infinite) double number.
239     */
240    public boolean isNaN() {
241        return isNaN(value);
242    }
243
244    /**
245     * Indicates whether the specified double is a <em>Not-a-Number (NaN)</em>
246     * value.
247     *
248     * @param d
249     *            the double value to check.
250     * @return {@code true} if {@code d} is <em>Not-a-Number</em>;
251     *         {@code false} if it is a (potentially infinite) double number.
252     */
253    public static boolean isNaN(double d) {
254        return d != d;
255    }
256
257    /**
258     * Converts the specified IEEE 754 floating-point double precision bit
259     * pattern to a Java double value.
260     *
261     * @param bits
262     *            the IEEE 754 floating-point double precision representation of
263     *            a double value.
264     * @return the double value converted from {@code bits}.
265     * @see #doubleToLongBits(double)
266     * @see #doubleToRawLongBits(double)
267     */
268    public static native double longBitsToDouble(long bits);
269
270    @Override
271    public long longValue() {
272        return (long) value;
273    }
274
275    /**
276     * Parses the specified string as a double value.
277     *
278     * @param string
279     *            the string representation of a double value.
280     * @return the primitive double value represented by {@code string}.
281     * @throws NumberFormatException
282     *             if {@code string} is {@code null}, has a length of zero or
283     *             can not be parsed as a double value.
284     */
285    public static double parseDouble(String string)
286            throws NumberFormatException {
287        return org.apache.harmony.luni.util.FloatingPointParser
288                .parseDouble(string);
289    }
290
291    @Override
292    public short shortValue() {
293        return (short) value;
294    }
295
296    @Override
297    public String toString() {
298        return Double.toString(value);
299    }
300
301    /**
302     * Returns a string containing a concise, human-readable description of the
303     * specified double value.
304     *
305     * @param d
306     *             the double to convert to a string.
307     * @return a printable representation of {@code d}.
308     */
309    public static String toString(double d) {
310        return org.apache.harmony.luni.util.NumberConverter.convert(d);
311    }
312
313    /**
314     * Parses the specified string as a double value.
315     *
316     * @param string
317     *            the string representation of a double value.
318     * @return a {@code Double} instance containing the double value represented
319     *         by {@code string}.
320     * @throws NumberFormatException
321     *             if {@code string} is {@code null}, has a length of zero or
322     *             can not be parsed as a double value.
323     * @see #parseDouble(String)
324     */
325    public static Double valueOf(String string) throws NumberFormatException {
326        return parseDouble(string);
327    }
328
329    /**
330     * Compares the two specified double values. There are two special cases:
331     * <ul>
332     * <li>{@code Double.NaN} is equal to {@code Double.NaN} and it is greater
333     * than any other double value, including {@code Double.POSITIVE_INFINITY};</li>
334     * <li>+0.0d is greater than -0.0d</li>
335     * </ul>
336     *
337     * @param double1
338     *            the first value to compare.
339     * @param double2
340     *            the second value to compare.
341     * @return a negative value if {@code double1} is less than {@code double2};
342     *         0 if {@code double1} and {@code double2} are equal; a positive
343     *         value if {@code double1} is greater than {@code double2}.
344     */
345    public static int compare(double double1, double double2) {
346        // Non-zero, non-NaN checking.
347        if (double1 > double2) {
348            return 1;
349        }
350        if (double2 > double1) {
351            return -1;
352        }
353        if (double1 == double2 && 0.0d != double1) {
354            return 0;
355        }
356
357        // NaNs are equal to other NaNs and larger than any other double
358        if (isNaN(double1)) {
359            if (isNaN(double2)) {
360                return 0;
361            }
362            return 1;
363        } else if (isNaN(double2)) {
364            return -1;
365        }
366
367        // Deal with +0.0 and -0.0
368        long d1 = doubleToRawLongBits(double1);
369        long d2 = doubleToRawLongBits(double2);
370        // The below expression is equivalent to:
371        // (d1 == d2) ? 0 : (d1 < d2) ? -1 : 1
372        return (int) ((d1 >> 63) - (d2 >> 63));
373    }
374
375    /**
376     * Returns a {@code Double} instance for the specified double value.
377     *
378     * @param d
379     *            the double value to store in the instance.
380     * @return a {@code Double} instance containing {@code d}.
381     * @since 1.5
382     */
383    public static Double valueOf(double d) {
384        return new Double(d);
385    }
386
387    /**
388     * Converts the specified double into its hexadecimal string representation.
389     *
390     * @param d
391     *            the double to convert.
392     * @return the hexadecimal string representation of {@code d}.
393     * @since 1.5
394     */
395    public static String toHexString(double d) {
396        /*
397         * Reference: http://en.wikipedia.org/wiki/IEEE_754
398         */
399        if (d != d) {
400            return "NaN"; //$NON-NLS-1$
401        }
402        if (d == POSITIVE_INFINITY) {
403            return "Infinity"; //$NON-NLS-1$
404        }
405        if (d == NEGATIVE_INFINITY) {
406            return "-Infinity"; //$NON-NLS-1$
407        }
408
409        long bitValue = doubleToLongBits(d);
410
411        boolean negative = (bitValue & 0x8000000000000000L) != 0;
412        // mask exponent bits and shift down
413        long exponent = (bitValue & 0x7FF0000000000000L) >>> 52;
414        // mask significand bits and shift up
415        long significand = bitValue & 0x000FFFFFFFFFFFFFL;
416
417        if (exponent == 0 && significand == 0) {
418            return (negative ? "-0x0.0p0" : "0x0.0p0"); //$NON-NLS-1$ //$NON-NLS-2$
419        }
420
421        StringBuilder hexString = new StringBuilder(10);
422        if (negative) {
423            hexString.append("-0x"); //$NON-NLS-1$
424        } else {
425            hexString.append("0x"); //$NON-NLS-1$
426        }
427
428        if (exponent == 0) { // denormal (subnormal) value
429            hexString.append("0."); //$NON-NLS-1$
430            // significand is 52-bits, so there can be 13 hex digits
431            int fractionDigits = 13;
432            // remove trailing hex zeros, so Integer.toHexString() won't print
433            // them
434            while ((significand != 0) && ((significand & 0xF) == 0)) {
435                significand >>>= 4;
436                fractionDigits--;
437            }
438            // this assumes Integer.toHexString() returns lowercase characters
439            String hexSignificand = Long.toHexString(significand);
440
441            // if there are digits left, then insert some '0' chars first
442            if (significand != 0 && fractionDigits > hexSignificand.length()) {
443                int digitDiff = fractionDigits - hexSignificand.length();
444                while (digitDiff-- != 0) {
445                    hexString.append('0');
446                }
447            }
448            hexString.append(hexSignificand);
449            hexString.append("p-1022"); //$NON-NLS-1$
450        } else { // normal value
451            hexString.append("1."); //$NON-NLS-1$
452            // significand is 52-bits, so there can be 13 hex digits
453            int fractionDigits = 13;
454            // remove trailing hex zeros, so Integer.toHexString() won't print
455            // them
456            while ((significand != 0) && ((significand & 0xF) == 0)) {
457                significand >>>= 4;
458                fractionDigits--;
459            }
460            // this assumes Integer.toHexString() returns lowercase characters
461            String hexSignificand = Long.toHexString(significand);
462
463            // if there are digits left, then insert some '0' chars first
464            if (significand != 0 && fractionDigits > hexSignificand.length()) {
465                int digitDiff = fractionDigits - hexSignificand.length();
466                while (digitDiff-- != 0) {
467                    hexString.append('0');
468                }
469            }
470
471            hexString.append(hexSignificand);
472            hexString.append('p');
473            // remove exponent's 'bias' and convert to a string
474            hexString.append(Long.toString(exponent - 1023));
475        }
476        return hexString.toString();
477    }
478}
479