1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.Double;
13 
14 import hunt.Exceptions;
15 import hunt.Nullable;
16 import hunt.Number;
17 
18 import std.conv;
19 import std.math;
20 
21 class Double : AbstractNumber!double {
22     
23     /**
24      * A constant holding the positive infinity of type
25      * {@code double}. It is equal to the value returned by
26      * {@code Double.longBitsToDouble(0x7ff0000000000000L)}.
27      */
28     enum double POSITIVE_INFINITY = double.infinity; //1.0 / 0.0;
29 
30     /**
31      * A constant holding the negative infinity of type
32      * {@code double}. It is equal to the value returned by
33      * {@code Double.longBitsToDouble(0xfff0000000000000L)}.
34      */
35     enum double NEGATIVE_INFINITY = -double.infinity; // -1.0 / 0.0;
36 
37     /**
38      * A constant holding a Not-a-Number (NaN) value of type
39      * {@code double}. It is equivalent to the value returned by
40      * {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
41      */
42     enum double NaN = double.nan; // 0.0d / 0.0;
43 
44     /**
45      * A constant holding the largest positive finite value of type
46      * {@code double},
47      * (2-2<sup>-52</sup>)&middot;2<sup>1023</sup>.  It is equal to
48      * the hexadecimal floating-point literal
49      * {@code 0x1.fffffffffffffP+1023} and also equal to
50      * {@code Double.longBitsToDouble(0x7fefffffffffffffL)}.
51      */
52     enum double MAX_VALUE = double.max; // 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
53 
54     /**
55      * A constant holding the smallest positive normal value of type
56      * {@code double}, 2<sup>-1022</sup>.  It is equal to the
57      * hexadecimal floating-point literal {@code 0x1.0p-1022} and also
58      * equal to {@code Double.longBitsToDouble(0x0010000000000000L)}.
59      *
60      */
61     enum double MIN_NORMAL = double.min_normal; // 0x1.0p-1022; // 2.2250738585072014E-308
62 
63     /**
64      * A constant holding the smallest positive nonzero value of type
65      * {@code double}, 2<sup>-1074</sup>. It is equal to the
66      * hexadecimal floating-point literal
67      * {@code 0x0.0000000000001P-1022} and also equal to
68      * {@code Double.longBitsToDouble(0x1L)}.
69      */
70     enum double MIN_VALUE = double.min_10_exp; // 0x0.0000000000001P-1022; // 4.9e-324
71 
72     /**
73      * Maximum exponent a finite {@code double} variable may have.
74      * It is equal to the value returned by
75      * {@code Math.getExponent(Double.MAX_VALUE)}.
76      *
77      */
78     enum int MAX_EXPONENT = 1023;
79 
80     /**
81      * Minimum exponent a normalized {@code double} variable may
82      * have.  It is equal to the value returned by
83      * {@code Math.getExponent(Double.MIN_NORMAL)}.
84      *
85      */
86     enum int MIN_EXPONENT = -1022;
87 
88     /**
89      * The number of bits used to represent a {@code double} value.
90      *
91      */
92     enum int SIZE = 64;
93 
94     /**
95      * The number of bytes used to represent a {@code double} value.
96      *
97      */
98     enum int BYTES = SIZE / 8;
99 
100 
101     /**
102      * Returns a representation of the specified floating-point value
103      * according to the IEEE 754 floating-point "double
104      * format" bit layout.
105      *
106      * <p>Bit 63 (the bit that is selected by the mask
107      * {@code 0x8000000000000000L}) represents the sign of the
108      * floating-point number. Bits
109      * 62-52 (the bits that are selected by the mask
110      * {@code 0x7ff0000000000000L}) represent the exponent. Bits 51-0
111      * (the bits that are selected by the mask
112      * {@code 0x000fffffffffffffL}) represent the significand
113      * (sometimes called the mantissa) of the floating-point number.
114      *
115      * <p>If the argument is positive infinity, the result is
116      * {@code 0x7ff0000000000000L}.
117      *
118      * <p>If the argument is negative infinity, the result is
119      * {@code 0xfff0000000000000L}.
120      *
121      * <p>If the argument is NaN, the result is
122      * {@code 0x7ff8000000000000L}.
123      *
124      * <p>In all cases, the result is a {@code long} integer that, when
125      * given to the {@link #longBitsToDouble(long)} method, will produce a
126      * floating-point value the same as the argument to
127      * {@code doubleToLongBits} (except all NaN values are
128      * collapsed to a single "canonical" NaN value).
129      *
130      * @param   value   a {@code double} precision floating-point number.
131      * @return the bits that represent the floating-point number.
132      */
133     static long doubleToLongBits(double value) @trusted nothrow {
134         if (!isNaN(value)) {
135             return doubleToRawLongBits(value);
136         }
137         return 0x7ff8000000000000L;
138     }
139 
140     /**
141      * Returns a representation of the specified floating-point value
142      * according to the IEEE 754 floating-point "double
143      * format" bit layout, preserving Not-a-Number (NaN) values.
144      *
145      * <p>Bit 63 (the bit that is selected by the mask
146      * {@code 0x8000000000000000L}) represents the sign of the
147      * floating-point number. Bits
148      * 62-52 (the bits that are selected by the mask
149      * {@code 0x7ff0000000000000L}) represent the exponent. Bits 51-0
150      * (the bits that are selected by the mask
151      * {@code 0x000fffffffffffffL}) represent the significand
152      * (sometimes called the mantissa) of the floating-point number.
153      *
154      * <p>If the argument is positive infinity, the result is
155      * {@code 0x7ff0000000000000L}.
156      *
157      * <p>If the argument is negative infinity, the result is
158      * {@code 0xfff0000000000000L}.
159      *
160      * <p>If the argument is NaN, the result is the {@code long}
161      * integer representing the actual NaN value.  Unlike the
162      * {@code doubleToLongBits} method,
163      * {@code doubleToRawLongBits} does not collapse all the bit
164      * patterns encoding a NaN to a single "canonical" NaN
165      * value.
166      *
167      * <p>In all cases, the result is a {@code long} integer that,
168      * when given to the {@link #longBitsToDouble(long)} method, will
169      * produce a floating-point value the same as the argument to
170      * {@code doubleToRawLongBits}.
171      *
172      * @param   value   a {@code double} precision floating-point number.
173      * @return the bits that represent the floating-point number.
174      */
175     static long doubleToRawLongBits(double value) @trusted nothrow {
176         byte* ptr = cast(byte*)&value;
177         // trace("%(%02X %)", ptr[0..double.sizeof]);
178         return *(cast(long*)ptr);
179     }
180 
181     /**
182      * Returns the {@code double} value corresponding to a given
183      * bit representation.
184      * The argument is considered to be a representation of a
185      * floating-point value according to the IEEE 754 floating-point
186      * "double format" bit layout.
187      *
188      * <p>If the argument is {@code 0x7ff0000000000000L}, the result
189      * is positive infinity.
190      *
191      * <p>If the argument is {@code 0xfff0000000000000L}, the result
192      * is negative infinity.
193      *
194      * <p>If the argument is any value in the range
195      * {@code 0x7ff0000000000001L} through
196      * {@code 0x7fffffffffffffffL} or in the range
197      * {@code 0xfff0000000000001L} through
198      * {@code 0xffffffffffffffffL}, the result is a NaN.  No IEEE
199      * 754 floating-point operation provided by Java can distinguish
200      * between two NaN values of the same type with different bit
201      * patterns.  Distinct values of NaN are only distinguishable by
202      * use of the {@code Double.doubleToRawLongBits} method.
203      *
204      * <p>In all other cases, let <i>s</i>, <i>e</i>, and <i>m</i> be three
205      * values that can be computed from the argument:
206      *
207      * <blockquote><pre>{@code
208      * int s = ((bits >> 63) == 0) ? 1 : -1;
209      * int e = (int)((bits >> 52) & 0x7ffL);
210      * long m = (e == 0) ?
211      *                 (bits & 0xfffffffffffffL) << 1 :
212      *                 (bits & 0xfffffffffffffL) | 0x10000000000000L;
213      * }</pre></blockquote>
214      *
215      * Then the floating-point result equals the value of the mathematical
216      * expression <i>s</i>&middot;<i>m</i>&middot;2<sup><i>e</i>-1075</sup>.
217      *
218      * <p>Note that this method may not be able to return a
219      * {@code double} NaN with exactly same bit pattern as the
220      * {@code long} argument.  IEEE 754 distinguishes between two
221      * kinds of NaNs, quiet NaNs and <i>signaling NaNs</i>.  The
222      * differences between the two kinds of NaN are generally not
223      * visible in Java.  Arithmetic operations on signaling NaNs turn
224      * them into quiet NaNs with a different, but often similar, bit
225      * pattern.  However, on some processors merely copying a
226      * signaling NaN also performs that conversion.  In particular,
227      * copying a signaling NaN to return it to the calling method
228      * may perform this conversion.  So {@code longBitsToDouble}
229      * may not be able to return a {@code double} with a
230      * signaling NaN bit pattern.  Consequently, for some
231      * {@code long} values,
232      * {@code doubleToRawLongBits(longBitsToDouble(start))} may
233      * <i>not</i> equal {@code start}.  Moreover, which
234      * particular bit patterns represent signaling NaNs is platform
235      * dependent; although all NaN bit patterns, quiet or signaling,
236      * must be in the NaN range identified above.
237      *
238      * @param   bits   any {@code long} integer.
239      * @return  the {@code double} floating-point value with the same
240      *          bit pattern.
241      */
242     static double longBitsToDouble(long bits) {
243         byte* ptr = cast(byte*)&bits;
244         // trace("%(%02X %)", ptr[0..double.sizeof]);
245         return *(cast(double*)ptr);
246     }
247 
248     /**
249      * The value of the Double.
250      *
251      * @serial
252      */
253     // private  double value;
254 
255     /**
256      * Constructs a newly allocated {@code Double} object that
257      * represents the primitive {@code double} argument.
258      *
259      * @param   value   the value to be represented by the {@code Double}.
260      */
261     this(double value) {
262         super(value);
263     }
264 
265     /**
266      * Constructs a newly allocated {@code Double} object that
267      * represents the floating-point value of type {@code double}
268      * represented by the string. The string is converted to a
269      * {@code double} value as if by the {@code valueOf} method.
270      *
271      * @param  s  a string to be converted to a {@code Double}.
272      * @throws    NumberFormatException  if the string does not contain a
273      *            parsable number.
274      * @see       java.lang.Double#valueOf(java.lang.string)
275      */
276     this(string s) {
277         super(parseDouble(s));
278     }
279 
280     /**
281      * Returns {@code true} if this {@code Double} value is
282      * a Not-a-Number (NaN), {@code false} otherwise.
283      *
284      * @return  {@code true} if the value represented by this object is
285      *          NaN; {@code false} otherwise.
286      */
287     bool isNaN() @trusted nothrow {
288         return isNaN(value);
289     }
290 
291     /**
292      * Returns {@code true} if this {@code Double} value is
293      * infinitely large in magnitude, {@code false} otherwise.
294      *
295      * @return  {@code true} if the value represented by this object is
296      *          positive infinity or negative infinity;
297      *          {@code false} otherwise.
298      */
299     bool isInfinite() {
300         return isInfinite(value);
301     }
302 
303     /**
304      * Returns a hash code for a {@code double} value; compatible with
305      * {@code Double.hashCode()}.
306      *
307      * @param value the value to hash
308      * @return a hash code value for a {@code double} value.
309      */
310     override size_t toHash() @safe nothrow {
311         return hashOf(value);
312     }
313 
314     static double parseDouble(string s) {
315         return to!double(s);
316     }
317 
318     /**
319      * Returns {@code true} if this {@code Double} value is
320      * a Not-a-Number (NaN), {@code false} otherwise.
321      *
322      * @return  {@code true} if the value represented by this object is
323      *          NaN; {@code false} otherwise.
324      */
325     static bool isNaN(double v) @trusted nothrow {
326         return std.math.isNaN(v);
327     }
328 
329     /**
330      * Returns {@code true} if the specified number is infinitely
331      * large in magnitude, {@code false} otherwise.
332      *
333      * @param   v   the value to be tested.
334      * @return  {@code true} if the value of the argument is positive
335      *          infinity or negative infinity; {@code false} otherwise.
336      */
337     static bool isInfinite(double v) {
338         return std.math.isInfinity(v);
339     }
340 
341     /**
342      * Returns {@code true} if the argument is a finite floating-point
343      * value; returns {@code false} otherwise (for NaN and infinity
344      * arguments).
345      *
346      * @param d the {@code double} value to be tested
347      * @return {@code true} if the argument is a finite
348      * floating-point value, {@code false} otherwise.
349      */
350     static bool isFinite(double d) {
351         return std.math.isInfinity(d);
352     }
353 
354     /**
355      * Returns a {@code Double} instance representing the specified
356      * {@code double} value.
357      * If a new {@code Double} instance is not required, this method
358      * should generally be used in preference to the constructor
359      * {@link #Double(double)}, as this method is likely to yield
360      * significantly better space and time performance by caching
361      * frequently requested values.
362      *
363      * @param  d a double value.
364      * @return a {@code Double} instance representing {@code d}.
365      */
366     static Double valueOf(double d) {
367         return new Double(d);
368     }
369 }
370 
371 
372 /**
373  * This class contains additional constants documenting limits of the
374  * {@code double} type.
375  *
376  * @author Joseph D. Darcy
377  */
378 
379 class DoubleConsts {
380     /**
381      * Don't let anyone instantiate this class.
382      */
383     private this() {}
384 
385     /**
386      * The number of logical bits in the significand of a
387      * {@code double} number, including the implicit bit.
388      */
389     enum int SIGNIFICAND_WIDTH   = 53;
390 
391     /**
392      * The exponent the smallest positive {@code double}
393      * subnormal value would have if it could be normalized..
394      */
395     enum int MIN_SUB_EXPONENT = Double.MIN_EXPONENT -
396                                                    (SIGNIFICAND_WIDTH - 1);
397 
398     /**
399      * Bias used in representing a {@code double} exponent.
400      */
401     enum int EXP_BIAS        = 1023;
402 
403     /**
404      * Bit mask to isolate the sign bit of a {@code double}.
405      */
406     enum long SIGN_BIT_MASK   = 0x8000000000000000L;
407 
408     /**
409      * Bit mask to isolate the exponent field of a
410      * {@code double}.
411      */
412     enum long EXP_BIT_MASK    = 0x7FF0000000000000L;
413 
414     /**
415      * Bit mask to isolate the significand field of a
416      * {@code double}.
417      */
418     enum long SIGNIF_BIT_MASK = 0x000FFFFFFFFFFFFFL;
419 
420     // static {
421     //     // verify bit masks cover all bit positions and that the bit
422     //     // masks are non-overlapping
423     //     assert(((SIGN_BIT_MASK | EXP_BIT_MASK | SIGNIF_BIT_MASK) == ~0L) &&
424     //            (((SIGN_BIT_MASK & EXP_BIT_MASK) == 0L) &&
425     //             ((SIGN_BIT_MASK & SIGNIF_BIT_MASK) == 0L) &&
426     //             ((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0L)));
427     // }
428 
429 }