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