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