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>)·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>·<i>m</i>·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 }