|
200 | 200 | * floating-point values, the three relations only differ if at least
|
201 | 201 | * one argument is zero or NaN.
|
202 | 202 | *
|
| 203 | + * <h2><a id=decimalToBinaryConversion>Decimal ↔ Binary Conversion Issues</a></h2> |
| 204 | + * |
| 205 | + * Many surprising results of binary floating-point arithmetic trace |
| 206 | + * back to aspects of decimal to binary conversion and binary to |
| 207 | + * decimal conversion. While integer values can be exactly represented |
| 208 | + * in any base, which fractional values can be exactly represented in |
| 209 | + * a base is a function of the base. For example, in base 10, 1/3 is a |
| 210 | + * repeating fraction (0.33333....); but in base 3, 1/3 is exactly |
| 211 | + * 0.1<sub>(3)</sub>, that is 1 × 3<sup>-1</sup>. |
| 212 | + * Similarly, in base 10, 1/10 is exactly representable as 0.1 |
| 213 | + * (1 × 10<sup>-1</sup>), but in base 2, it is a |
| 214 | + * repeating fraction (0.0001100110011...<sub>(2)</sub>). |
| 215 | + * |
| 216 | + * <p>Values of the {@code float} type have {@value Float#PRECISION} |
| 217 | + * bits of precision and values of the {@code double} type have |
| 218 | + * {@value Double#PRECISION} bits of precision. Therefore, since 0.1 |
| 219 | + * is a repeating fraction in base 2 with a four-bit repeat, {@code |
| 220 | + * 0.1f} != {@code 0.1d}. In more detail, including hexadecimal |
| 221 | + * floating-point literals: |
| 222 | + * |
| 223 | + * <ul> |
| 224 | + * <li>The exact numerical value of {@code 0.1f} ({@code 0x1.99999a0000000p-4f}) is |
| 225 | + * 0.100000001490116119384765625. |
| 226 | + * <li>The exact numerical value of {@code 0.1d} ({@code 0x1.999999999999ap-4d}) is |
| 227 | + * 0.1000000000000000055511151231257827021181583404541015625. |
| 228 | + * </ul> |
| 229 | + * |
| 230 | + * These are the closest {@code float} and {@code double} values, |
| 231 | + * respectively, to the numerical value of 0.1. These results are |
| 232 | + * consistent with a {@code float} value having the equivalent of 6 to |
| 233 | + * 9 digits of decimal precision and a {@code double} value having the |
| 234 | + * equivalent of 15 to 17 digits of decimal precision. (The |
| 235 | + * equivalent precision varies according to the different relative |
| 236 | + * densities of binary and decimal values at different points along the |
| 237 | + * real number line). |
| 238 | + * |
| 239 | + * <p>This representation hazard of decimal fractions is one reason to |
| 240 | + * use caution when storing monetary values as {@code float} or {@code |
| 241 | + * double}. Alternatives include: |
| 242 | + * <ul> |
| 243 | + * <li>using {@link java.math.BigDecimal BigDecimal} to store decimal |
| 244 | + * fractional values exactly |
| 245 | + * |
| 246 | + * <li>scaling up so the monetary value is an integer — for |
| 247 | + * example, multiplying by 100 if the value is denominated in cents or |
| 248 | + * multiplying by 1000 if the value is denominated in mills — |
| 249 | + * and then storing that scaled value in an integer type |
| 250 | + * |
| 251 | + *</ul> |
| 252 | + * |
| 253 | + * <p>For each finite floating-point value and a given floating-point |
| 254 | + * type, there is a contiguous region of the real number line which |
| 255 | + * maps to that value. Under the default round to nearest rounding |
| 256 | + * policy (JLS {@jls 15.4}), this contiguous region for a value is |
| 257 | + * typically one {@linkplain Math#ulp ulp} (unit in the last place) |
| 258 | + * wide and centered around the exactly representable value. (At |
| 259 | + * exponent boundaries, the region is asymmetrical and larger on the |
| 260 | + * side with the larger exponent.) For example, for {@code 0.1f}, the |
| 261 | + * region can be computed as follows: |
| 262 | + * |
| 263 | + * <br>// Numeric values listed are exact values |
| 264 | + * <br>oneTenthApproxAsFloat = 0.100000001490116119384765625; |
| 265 | + * <br>ulpOfoneTenthApproxAsFloat = Math.ulp(0.1f) = 7.450580596923828125E-9; |
| 266 | + * <br>// Numeric range that is converted to the float closest to 0.1, _excludes_ endpoints |
| 267 | + * <br>(oneTenthApproxAsFloat - ½ulpOfoneTenthApproxAsFloat, oneTenthApproxAsFloat + ½ulpOfoneTenthApproxAsFloat) = |
| 268 | + * <br>(0.0999999977648258209228515625, 0.1000000052154064178466796875) |
| 269 | + * |
| 270 | + * <p>In particular, a correctly rounded decimal to binary conversion |
| 271 | + * of any string representing a number in this range, say by {@link |
| 272 | + * Float#parseFloat(String)}, will be converted to the same value: |
| 273 | + * |
| 274 | + * {@snippet lang="java" : |
| 275 | + * Float.parseFloat("0.0999999977648258209228515625000001"); // rounds up to oneTenthApproxAsFloat |
| 276 | + * Float.parseFloat("0.099999998"); // rounds up to oneTenthApproxAsFloat |
| 277 | + * Float.parseFloat("0.1"); // rounds up to oneTenthApproxAsFloat |
| 278 | + * Float.parseFloat("0.100000001490116119384765625"); // exact conversion |
| 279 | + * Float.parseFloat("0.100000005215406417846679687"); // rounds down to oneTenthApproxAsFloat |
| 280 | + * Float.parseFloat("0.100000005215406417846679687499999"); // rounds down to oneTenthApproxAsFloat |
| 281 | + * } |
| 282 | + * |
| 283 | + * <p>Similarly, an analogous range can be constructed for the {@code |
| 284 | + * double} type based on the exact value of {@code double} |
| 285 | + * approximation to {@code 0.1d} and the numerical value of {@code |
| 286 | + * Math.ulp(0.1d)} and likewise for other particular numerical values |
| 287 | + * in the {@code float} and {@code double} types. |
| 288 | + * |
| 289 | + * <p>As seen in the above conversions, compared to the exact |
| 290 | + * numerical value the operation would have without rounding, the same |
| 291 | + * floating-point value as a result can be: |
| 292 | + * <ul> |
| 293 | + * <li>greater than the exact result |
| 294 | + * <li>equal to the exact result |
| 295 | + * <li>less than the exact result |
| 296 | + * </ul> |
| 297 | + * |
| 298 | + * A floating-point value doesn't "know" whether it was the result of |
| 299 | + * rounding up, or rounding down, or an exact operation; it contains |
| 300 | + * no history of how it was computed. Consequently, the sum of |
| 301 | + * {@snippet lang="java" : |
| 302 | + * 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f; |
| 303 | + * // Numerical value of computed sum: 1.00000011920928955078125, |
| 304 | + * // the next floating-point value larger than 1.0f, equal to Math.nextUp(1.0f). |
| 305 | + * } |
| 306 | + * or |
| 307 | + * {@snippet lang="java" : |
| 308 | + * 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d; |
| 309 | + * // Numerical value of computed sum: 0.99999999999999988897769753748434595763683319091796875, |
| 310 | + * // the next floating-point value smaller than 1.0d, equal to Math.nextDown(1.0d). |
| 311 | + * } |
| 312 | + * |
| 313 | + * should <em>not</em> be expected to be exactly equal to 1.0, but |
| 314 | + * only to be close to 1.0. Consequently, the following code is an |
| 315 | + * infinite loop: |
| 316 | + * |
| 317 | + * {@snippet lang="java" : |
| 318 | + * double d = 0.0; |
| 319 | + * while(d != 1.0) { // Surprising infinite loop |
| 320 | + * d += 0.1; // Sum never _exactly_ equals 1.0 |
| 321 | + * } |
| 322 | + * } |
| 323 | + * |
| 324 | + * Instead, use an integer loop count for counted loops: |
| 325 | + * |
| 326 | + * {@snippet lang="java" : |
| 327 | + * double d = 0.0; |
| 328 | + * for(int i = 0; i < 10; i++) { |
| 329 | + * d += 0.1; |
| 330 | + * } // Value of d is equal to Math.nextDown(1.0). |
| 331 | + * } |
| 332 | + * |
| 333 | + * or test against a floating-point limit using ordered comparisons |
| 334 | + * ({@code <}, {@code <=}, {@code >}, {@code >=}): |
| 335 | + * |
| 336 | + * {@snippet lang="java" : |
| 337 | + * double d = 0.0; |
| 338 | + * while(d <= 1.0) { |
| 339 | + * d += 0.1; |
| 340 | + * } // Value of d approximately 1.0999999999999999 |
| 341 | + * } |
| 342 | + * |
| 343 | + * While floating-point arithmetic may have surprising results, IEEE |
| 344 | + * 754 floating-point arithmetic follows a principled design and its |
| 345 | + * behavior is predictable on the Java platform. |
| 346 | + * |
203 | 347 | * @jls 4.2.3 Floating-Point Types, Formats, and Values
|
204 | 348 | * @jls 4.2.4. Floating-Point Operations
|
205 | 349 | * @jls 15.21.1 Numerical Equality Operators == and !=
|
@@ -750,6 +894,7 @@ public static String toHexString(double d) {
|
750 | 894 | * represented by the {@code String} argument.
|
751 | 895 | * @throws NumberFormatException if the string does not contain a
|
752 | 896 | * parsable number.
|
| 897 | + * @see Double##decimalToBinaryConversion Decimal ↔ Binary Conversion Issues |
753 | 898 | */
|
754 | 899 | public static Double valueOf(String s) throws NumberFormatException {
|
755 | 900 | return new Double(parseDouble(s));
|
@@ -786,6 +931,7 @@ public static Double valueOf(double d) {
|
786 | 931 | * @throws NumberFormatException if the string does not contain
|
787 | 932 | * a parsable {@code double}.
|
788 | 933 | * @see java.lang.Double#valueOf(String)
|
| 934 | + * @see Double##decimalToBinaryConversion Decimal ↔ Binary Conversion Issues |
789 | 935 | * @since 1.2
|
790 | 936 | */
|
791 | 937 | public static double parseDouble(String s) throws NumberFormatException {
|
|
0 commit comments