src/share/classes/java/lang/Math.java

Print this page
rev 7994 : 8010430: Math.round has surprising behavior for odd values of ulp 1
Summary: If the effective floating point exponent is zero return the significand including the implicit 1-bit.
Reviewed-by: bpb, darcy, gls
Contributed-by: Dmitry Nadezhin <dmitry.nadezhin@oracle.com>
   1 /*
   2  * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 629      * considered to be an integer if and only if it is finite and a
 630      * fixed point of the method {@link #ceil ceil} or,
 631      * equivalently, a fixed point of the method {@link #floor
 632      * floor}. A value is a fixed point of a one-argument
 633      * method if and only if the result of applying the method to the
 634      * value is equal to the value.)
 635      *
 636      * <p>The computed result must be within 1 ulp of the exact result.
 637      * Results must be semi-monotonic.
 638      *
 639      * @param   a   the base.
 640      * @param   b   the exponent.
 641      * @return  the value {@code a}<sup>{@code b}</sup>.
 642      */
 643     public static double pow(double a, double b) {
 644         return StrictMath.pow(a, b); // default impl. delegates to StrictMath
 645     }
 646 
 647     /**
 648      * Returns the closest {@code int} to the argument, with ties
 649      * rounding up.
 650      *
 651      * <p>
 652      * Special cases:
 653      * <ul><li>If the argument is NaN, the result is 0.
 654      * <li>If the argument is negative infinity or any value less than or
 655      * equal to the value of {@code Integer.MIN_VALUE}, the result is
 656      * equal to the value of {@code Integer.MIN_VALUE}.
 657      * <li>If the argument is positive infinity or any value greater than or
 658      * equal to the value of {@code Integer.MAX_VALUE}, the result is
 659      * equal to the value of {@code Integer.MAX_VALUE}.</ul>
 660      *
 661      * @param   a   a floating-point value to be rounded to an integer.
 662      * @return  the value of the argument rounded to the nearest
 663      *          {@code int} value.
 664      * @see     java.lang.Integer#MAX_VALUE
 665      * @see     java.lang.Integer#MIN_VALUE
 666      */
 667     public static int round(float a) {
 668         if (a != 0x1.fffffep-2f) // greatest float value less than 0.5
 669             return (int)floor(a + 0.5f);
 670         else
 671             return 0;






















 672     }
 673 
 674     /**
 675      * Returns the closest {@code long} to the argument, with ties
 676      * rounding up.
 677      *
 678      * <p>Special cases:
 679      * <ul><li>If the argument is NaN, the result is 0.
 680      * <li>If the argument is negative infinity or any value less than or
 681      * equal to the value of {@code Long.MIN_VALUE}, the result is
 682      * equal to the value of {@code Long.MIN_VALUE}.
 683      * <li>If the argument is positive infinity or any value greater than or
 684      * equal to the value of {@code Long.MAX_VALUE}, the result is
 685      * equal to the value of {@code Long.MAX_VALUE}.</ul>
 686      *
 687      * @param   a   a floating-point value to be rounded to a
 688      *          {@code long}.
 689      * @return  the value of the argument rounded to the nearest
 690      *          {@code long} value.
 691      * @see     java.lang.Long#MAX_VALUE
 692      * @see     java.lang.Long#MIN_VALUE
 693      */
 694     public static long round(double a) {
 695         if (a != 0x1.fffffffffffffp-2) // greatest double value less than 0.5
 696             return (long)floor(a + 0.5d);
 697         else
 698             return 0;






















 699     }
 700 
 701     private static final class RandomNumberGeneratorHolder {
 702         static final Random randomNumberGenerator = new Random();
 703     }
 704 
 705     /**
 706      * Returns a {@code double} value with a positive sign, greater
 707      * than or equal to {@code 0.0} and less than {@code 1.0}.
 708      * Returned values are chosen pseudorandomly with (approximately)
 709      * uniform distribution from that range.
 710      *
 711      * <p>When this method is first called, it creates a single new
 712      * pseudorandom-number generator, exactly as if by the expression
 713      *
 714      * <blockquote>{@code new java.util.Random()}</blockquote>
 715      *
 716      * This new pseudorandom-number generator is used thereafter for
 717      * all calls to this method and is used nowhere else.
 718      *


   1 /*
   2  * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 629      * considered to be an integer if and only if it is finite and a
 630      * fixed point of the method {@link #ceil ceil} or,
 631      * equivalently, a fixed point of the method {@link #floor
 632      * floor}. A value is a fixed point of a one-argument
 633      * method if and only if the result of applying the method to the
 634      * value is equal to the value.)
 635      *
 636      * <p>The computed result must be within 1 ulp of the exact result.
 637      * Results must be semi-monotonic.
 638      *
 639      * @param   a   the base.
 640      * @param   b   the exponent.
 641      * @return  the value {@code a}<sup>{@code b}</sup>.
 642      */
 643     public static double pow(double a, double b) {
 644         return StrictMath.pow(a, b); // default impl. delegates to StrictMath
 645     }
 646 
 647     /**
 648      * Returns the closest {@code int} to the argument, with ties
 649      * rounding to positive infinity.
 650      *
 651      * <p>
 652      * Special cases:
 653      * <ul><li>If the argument is NaN, the result is 0.
 654      * <li>If the argument is negative infinity or any value less than or
 655      * equal to the value of {@code Integer.MIN_VALUE}, the result is
 656      * equal to the value of {@code Integer.MIN_VALUE}.
 657      * <li>If the argument is positive infinity or any value greater than or
 658      * equal to the value of {@code Integer.MAX_VALUE}, the result is
 659      * equal to the value of {@code Integer.MAX_VALUE}.</ul>
 660      *
 661      * @param   a   a floating-point value to be rounded to an integer.
 662      * @return  the value of the argument rounded to the nearest
 663      *          {@code int} value.
 664      * @see     java.lang.Integer#MAX_VALUE
 665      * @see     java.lang.Integer#MIN_VALUE
 666      */
 667     public static int round(float a) {
 668         int intBits = Float.floatToRawIntBits(a);
 669         int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK)
 670                 >> (FloatConsts.SIGNIFICAND_WIDTH - 1);
 671         int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2
 672                 + FloatConsts.EXP_BIAS) - biasedExp;
 673         if ((shift & -32) == 0) { // shift >= 0 && shift < 32
 674             // a is a finite number such that pow(2,-32) <= ulp(a) < 1
 675             int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK)
 676                     | (FloatConsts.SIGNIF_BIT_MASK + 1));
 677             if (intBits < 0) {
 678                 r = -r;
 679             }
 680             // In the comments below each Java expression evaluates to the value
 681             // the corresponding mathematical expression:
 682             // (r) evaluates to a / ulp(a)
 683             // (r >> shift) evaluates to floor(a * 2)
 684             // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
 685             // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
 686             return ((r >> shift) + 1) >> 1;
 687         } else {
 688             // a is either
 689             // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2
 690             // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
 691             // - an infinity or NaN
 692             return (int) a;
 693         }
 694     }
 695 
 696     /**
 697      * Returns the closest {@code long} to the argument, with ties
 698      * rounding to positive infinity.
 699      *
 700      * <p>Special cases:
 701      * <ul><li>If the argument is NaN, the result is 0.
 702      * <li>If the argument is negative infinity or any value less than or
 703      * equal to the value of {@code Long.MIN_VALUE}, the result is
 704      * equal to the value of {@code Long.MIN_VALUE}.
 705      * <li>If the argument is positive infinity or any value greater than or
 706      * equal to the value of {@code Long.MAX_VALUE}, the result is
 707      * equal to the value of {@code Long.MAX_VALUE}.</ul>
 708      *
 709      * @param   a   a floating-point value to be rounded to a
 710      *          {@code long}.
 711      * @return  the value of the argument rounded to the nearest
 712      *          {@code long} value.
 713      * @see     java.lang.Long#MAX_VALUE
 714      * @see     java.lang.Long#MIN_VALUE
 715      */
 716     public static long round(double a) {
 717         long longBits = Double.doubleToRawLongBits(a);
 718         long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK)
 719                 >> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
 720         long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2
 721                 + DoubleConsts.EXP_BIAS) - biasedExp;
 722         if ((shift & -64) == 0) { // shift >= 0 && shift < 64
 723             // a is a finite number such that pow(2,-64) <= ulp(a) < 1
 724             long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK)
 725                     | (DoubleConsts.SIGNIF_BIT_MASK + 1));
 726             if (longBits < 0) {
 727                 r = -r;
 728             }
 729             // In the comments below each Java expression evaluates to the value
 730             // the corresponding mathematical expression:
 731             // (r) evaluates to a / ulp(a)
 732             // (r >> shift) evaluates to floor(a * 2)
 733             // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
 734             // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
 735             return ((r >> shift) + 1) >> 1;
 736         } else {
 737             // a is either
 738             // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2
 739             // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
 740             // - an infinity or NaN
 741             return (long) a;
 742         }
 743     }
 744 
 745     private static final class RandomNumberGeneratorHolder {
 746         static final Random randomNumberGenerator = new Random();
 747     }
 748 
 749     /**
 750      * Returns a {@code double} value with a positive sign, greater
 751      * than or equal to {@code 0.0} and less than {@code 1.0}.
 752      * Returned values are chosen pseudorandomly with (approximately)
 753      * uniform distribution from that range.
 754      *
 755      * <p>When this method is first called, it creates a single new
 756      * pseudorandom-number generator, exactly as if by the expression
 757      *
 758      * <blockquote>{@code new java.util.Random()}</blockquote>
 759      *
 760      * This new pseudorandom-number generator is used thereafter for
 761      * all calls to this method and is used nowhere else.
 762      *