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.Float;
13 
14 import hunt.Exceptions;
15 import hunt.Nullable;
16 import hunt.Number;
17 import std.conv;
18 
19 class Float : AbstractNumber!float {
20     /**
21      * A constant holding the positive infinity of type
22      * {@code float}. It is equal to the value returned by
23      * {@code Float.intBitsToFloat(0x7f800000)}.
24      */
25     enum float POSITIVE_INFINITY = float.infinity; // 1.0f / 0.0f;
26 
27     /**
28      * A constant holding the negative infinity of type
29      * {@code float}. It is equal to the value returned by
30      * {@code Float.intBitsToFloat(0xff800000)}.
31      */
32     enum float NEGATIVE_INFINITY = -float.infinity; // -1.0f / 0.0f;
33 
34     /**
35      * A constant holding a Not-a-Number (NaN) value of type
36      * {@code float}.  It is equivalent to the value returned by
37      * {@code Float.intBitsToFloat(0x7fc00000)}.
38      */
39     enum float NaN = float.nan; // 0.0f / 0.0f;
40 
41     /**
42      * A constant holding the largest positive finite value of type
43      * {@code float}, (2-2<sup>-23</sup>)&middot;2<sup>127</sup>.
44      * It is equal to the hexadecimal floating-point literal
45      * {@code 0x1.fffffeP+127f} and also equal to
46      * {@code Float.intBitsToFloat(0x7f7fffff)}.
47      */
48     enum float MAX_VALUE = float.max; // 0x1.fffffeP+127f; // 3.4028235e+38f
49 
50     /**
51      * A constant holding the smallest positive normal value of type
52      * {@code float}, 2<sup>-126</sup>.  It is equal to the
53      * hexadecimal floating-point literal {@code 0x1.0p-126f} and also
54      * equal to {@code Float.intBitsToFloat(0x00800000)}.
55      *
56      * @since 1.6
57      */
58     enum float MIN_NORMAL = float.min_normal; // 0x1.0p-126f; // 1.17549435E-38f
59 
60     /**
61      * A constant holding the smallest positive nonzero value of type
62      * {@code float}, 2<sup>-149</sup>. It is equal to the
63      * hexadecimal floating-point literal {@code 0x0.000002P-126f}
64      * and also equal to {@code Float.intBitsToFloat(0x1)}.
65      */
66     enum float MIN_VALUE = float.min_10_exp; //0x0.000002P-126f; // 1.4e-45f
67 
68     /**
69      * Maximum exponent a finite {@code float} variable may have.  It
70      * is equal to the value returned by {@code
71      * Math.getExponent(Float.MAX_VALUE)}.
72      *
73      * @since 1.6
74      */
75     enum int MAX_EXPONENT = 127;
76 
77     /**
78      * Minimum exponent a normalized {@code float} variable may have.
79      * It is equal to the value returned by {@code
80      * Math.getExponent(Float.MIN_NORMAL)}.
81      *
82      * @since 1.6
83      */
84     enum int MIN_EXPONENT = -126;
85 
86     /**
87      * The number of bits used to represent a {@code float} value.
88      *
89      * @since 1.5
90      */
91     enum int SIZE = 32;
92 
93     /**
94      * The number of bytes used to represent a {@code float} value.
95      *
96      * @since 1.8
97      */
98     enum int BYTES = SIZE / 8;
99 
100 
101     /**
102      * Returns the {@code float} value corresponding to a given
103      * bit representation.
104      * The argument is considered to be a representation of a
105      * floating-point value according to the IEEE 754 floating-point
106      * "single format" bit layout.
107      *
108      * <p>If the argument is {@code 0x7f800000}, the result is positive
109      * infinity.
110      *
111      * <p>If the argument is {@code 0xff800000}, the result is negative
112      * infinity.
113      *
114      * <p>If the argument is any value in the range
115      * {@code 0x7f800001} through {@code 0x7fffffff} or in
116      * the range {@code 0xff800001} through
117      * {@code 0xffffffff}, the result is a NaN.  No IEEE 754
118      * floating-point operation provided by Java can distinguish
119      * between two NaN values of the same type with different bit
120      * patterns.  Distinct values of NaN are only distinguishable by
121      * use of the {@code Float.floatToRawIntBits} method.
122      *
123      * <p>In all other cases, let <i>s</i>, <i>e</i>, and <i>m</i> be three
124      * values that can be computed from the argument:
125      *
126      * <blockquote><pre>{@code
127      * int s = ((bits >> 31) == 0) ? 1 : -1;
128      * int e = ((bits >> 23) & 0xff);
129      * int m = (e == 0) ?
130      *                 (bits & 0x7fffff) << 1 :
131      *                 (bits & 0x7fffff) | 0x800000;
132      * }</pre></blockquote>
133      *
134      * Then the floating-point result equals the value of the mathematical
135      * expression <i>s</i>&middot;<i>m</i>&middot;2<sup><i>e</i>-150</sup>.
136      *
137      * <p>Note that this method may not be able to return a
138      * {@code float} NaN with exactly same bit pattern as the
139      * {@code int} argument.  IEEE 754 distinguishes between two
140      * kinds of NaNs, quiet NaNs and <i>signaling NaNs</i>.  The
141      * differences between the two kinds of NaN are generally not
142      * visible in Java.  Arithmetic operations on signaling NaNs turn
143      * them into quiet NaNs with a different, but often similar, bit
144      * pattern.  However, on some processors merely copying a
145      * signaling NaN also performs that conversion.  In particular,
146      * copying a signaling NaN to return it to the calling method may
147      * perform this conversion.  So {@code intBitsToFloat} may
148      * not be able to return a {@code float} with a signaling NaN
149      * bit pattern.  Consequently, for some {@code int} values,
150      * {@code floatToRawIntBits(intBitsToFloat(start))} may
151      * <i>not</i> equal {@code start}.  Moreover, which
152      * particular bit patterns represent signaling NaNs is platform
153      * dependent; although all NaN bit patterns, quiet or signaling,
154      * must be in the NaN range identified above.
155      *
156      * @param   bits   an integer.
157      * @return  the {@code float} floating-point value with the same bit
158      *          pattern.
159      */
160     static float intBitsToFloat(int bits) {
161         implementationMissing(false);
162         return 0;
163     }
164 
165     /**
166      * The value of the Float.
167      *
168      * @serial
169      */
170     // private  float value;
171 
172     /**
173      * Constructs a newly allocated {@code Float} object that
174      * represents the primitive {@code float} argument.
175      *
176      * @param   value   the value to be represented by the {@code Float}.
177      */
178     this(float value) {
179         // this.value = value;
180         super(value);
181     }
182 
183     /**
184      * Constructs a newly allocated {@code Float} object that
185      * represents the argument converted to type {@code float}.
186      *
187      * @param   value   the value to be represented by the {@code Float}.
188      */
189     this(double value) {
190         // this.value = cast(float)value;
191         super(cast(float)value);
192     }
193 
194 
195     static float parseFloat(string s) {
196         return to!float(s);
197     }
198 
199     /**
200      * Constructs a newly allocated {@code Float} object that
201      * represents the floating-point value of type {@code float}
202      * represented by the string. The string is converted to a
203      * {@code float} value as if by the {@code valueOf} method.
204      *
205      * @param      s   a string to be converted to a {@code Float}.
206      * @throws  NumberFormatException  if the string does not contain a
207      *               parsable number.
208      * @see        java.lang.Float#valueOf(java.lang.string)
209      */
210     // Float(string s) throws NumberFormatException {
211     //     value = parseFloat(s);
212     // }
213 
214     /**
215      * Returns {@code true} if this {@code Float} value is a
216      * Not-a-Number (NaN), {@code false} otherwise.
217      *
218      * @return  {@code true} if the value represented by this object is
219      *          NaN; {@code false} otherwise.
220      */
221     // bool isNaN() {
222     //     return isNaN(value);
223     // }
224 
225     /**
226      * Returns {@code true} if this {@code Float} value is
227      * infinitely large in magnitude, {@code false} otherwise.
228      *
229      * @return  {@code true} if the value represented by this object is
230      *          positive infinity or negative infinity;
231      *          {@code false} otherwise.
232      */
233     // bool isInfinite() {
234     //     return isInfinite(value);
235     // }
236 
237 
238     /**
239      * Returns a {@code Float} instance representing the specified
240      * {@code float} value.
241      * If a new {@code Float} instance is not required, this method
242      * should generally be used in preference to the constructor
243      * {@link #Float(float)}, as this method is likely to yield
244      * significantly better space and time performance by caching
245      * frequently requested values.
246      *
247      * @param  f a float value.
248      * @return a {@code Float} instance representing {@code f}.
249      * @since  1.5
250      */
251     static Float valueOf(float f) {
252         return new Float(f);
253     }
254 
255     /**
256      * Returns a hash code for a {@code double} value; compatible with
257      * {@code Double.hashCode()}.
258      *
259      * @param value the value to hash
260      * @return a hash code value for a {@code double} value.
261      * @since 1.8
262      */
263     override size_t toHash() @safe nothrow {
264         return hashOf(value);
265     }
266 
267 }
268 
269 
270 /**
271  * This class contains additional constants documenting limits of the
272  * {@code float} type.
273  *
274  * @author Joseph D. Darcy
275  */
276 
277 class FloatConsts {
278     /**
279      * Don't let anyone instantiate this class.
280      */
281     private this() {}
282 
283     /**
284      * The number of logical bits in the significand of a
285      * {@code float} number, including the implicit bit.
286      */
287     enum int SIGNIFICAND_WIDTH   = 24;
288 
289     /**
290      * The exponent the smallest positive {@code float} subnormal
291      * value would have if it could be normalized.
292      */
293     enum int     MIN_SUB_EXPONENT = Float.MIN_EXPONENT -
294                                                    (SIGNIFICAND_WIDTH - 1);
295 
296     /**
297      * Bias used in representing a {@code float} exponent.
298      */
299     enum int     EXP_BIAS        = 127;
300 
301     /**
302      * Bit mask to isolate the sign bit of a {@code float}.
303      */
304     enum int     SIGN_BIT_MASK   = 0x80000000;
305 
306     /**
307      * Bit mask to isolate the exponent field of a
308      * {@code float}.
309      */
310     enum int     EXP_BIT_MASK    = 0x7F800000;
311 
312     /**
313      * Bit mask to isolate the significand field of a
314      * {@code float}.
315      */
316     enum int     SIGNIF_BIT_MASK = 0x007FFFFF;
317 
318     // static {
319     //     // verify bit masks cover all bit positions and that the bit
320     //     // masks are non-overlapping
321     //     assert(((SIGN_BIT_MASK | EXP_BIT_MASK | SIGNIF_BIT_MASK) == ~0) &&
322     //            (((SIGN_BIT_MASK & EXP_BIT_MASK) == 0) &&
323     //             ((SIGN_BIT_MASK & SIGNIF_BIT_MASK) == 0) &&
324     //             ((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0)));
325     // }
326 }