jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java
changeset 34417 57a3863abbb4
child 34781 479b1724ab80
equal deleted inserted replaced
34416:68c0d866db5d 34417:57a3863abbb4
       
     1 /*
       
     2  * Copyright (c) 2015, 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
       
    23  * questions.
       
    24  */
       
    25 package sun.java2d.marlin;
       
    26 
       
    27 import sun.misc.DoubleConsts;
       
    28 import sun.misc.FloatConsts;
       
    29 
       
    30 /**
       
    31  * Faster Math ceil / floor routines derived from StrictMath
       
    32  */
       
    33 public final class FloatMath implements MarlinConst {
       
    34 
       
    35     // overflow / NaN handling enabled:
       
    36     static final boolean CHECK_OVERFLOW = true;
       
    37     static final boolean CHECK_NAN = true;
       
    38 
       
    39     private FloatMath() {
       
    40         // utility class
       
    41     }
       
    42 
       
    43     // faster inlined min/max functions in the branch prediction is high
       
    44     static float max(final float a, final float b) {
       
    45         // no NaN handling
       
    46         return (a >= b) ? a : b;
       
    47     }
       
    48 
       
    49     static int max(final int a, final int b) {
       
    50         return (a >= b) ? a : b;
       
    51     }
       
    52 
       
    53     static int min(final int a, final int b) {
       
    54         return (a <= b) ? a : b;
       
    55     }
       
    56 
       
    57     /**
       
    58      * Returns the smallest (closest to negative infinity) {@code float} value
       
    59      * that is greater than or equal to the argument and is equal to a
       
    60      * mathematical integer. Special cases:
       
    61      * <ul><li>If the argument value is already equal to a mathematical integer,
       
    62      * then the result is the same as the argument.  <li>If the argument is NaN
       
    63      * or an infinity or positive zero or negative zero, then the result is the
       
    64      * same as the argument.  <li>If the argument value is less than zero but
       
    65      * greater than -1.0, then the result is negative zero.</ul> Note that the
       
    66      * value of {@code StrictMath.ceil(x)} is exactly the value of
       
    67      * {@code -StrictMath.floor(-x)}.
       
    68      *
       
    69      * @param a a value.
       
    70      * @return the smallest (closest to negative infinity) floating-point value
       
    71      * that is greater than or equal to the argument and is equal to a
       
    72      * mathematical integer.
       
    73      */
       
    74     public static float ceil_f(final float a) {
       
    75         // Derived from StrictMath.ceil(double):
       
    76 
       
    77         // Inline call to Math.getExponent(a) to
       
    78         // compute only once Float.floatToRawIntBits(a)
       
    79         final int doppel = Float.floatToRawIntBits(a);
       
    80 
       
    81         final int exponent = ((doppel & FloatConsts.EXP_BIT_MASK)
       
    82                 >> (FloatConsts.SIGNIFICAND_WIDTH - 1))
       
    83                 - FloatConsts.EXP_BIAS;
       
    84 
       
    85         if (exponent < 0) {
       
    86             /*
       
    87              * Absolute value of argument is less than 1.
       
    88              * floorOrceil(-0.0) => -0.0
       
    89              * floorOrceil(+0.0) => +0.0
       
    90              */
       
    91             return ((a == 0) ? a :
       
    92                     ( (a < 0f) ? -0f : 1f) );
       
    93         }
       
    94         if (CHECK_OVERFLOW && (exponent >= 23)) { // 52 for double
       
    95             /*
       
    96              * Infinity, NaN, or a value so large it must be integral.
       
    97              */
       
    98             return a;
       
    99         }
       
   100         // Else the argument is either an integral value already XOR it
       
   101         // has to be rounded to one.
       
   102         assert exponent >= 0 && exponent <= 22; // 51 for double
       
   103 
       
   104         final int intpart = doppel
       
   105                 & (~(FloatConsts.SIGNIF_BIT_MASK >> exponent));
       
   106 
       
   107         if (intpart == doppel) {
       
   108             return a; // integral value (including 0)
       
   109         }
       
   110 
       
   111         // 0 handled above as an integer
       
   112         // sign: 1 for negative, 0 for positive numbers
       
   113         // add : 0 for negative and 1 for positive numbers
       
   114         return Float.intBitsToFloat(intpart) + ((~intpart) >>> 31);
       
   115     }
       
   116 
       
   117     /**
       
   118      * Returns the largest (closest to positive infinity) {@code float} value
       
   119      * that is less than or equal to the argument and is equal to a mathematical
       
   120      * integer. Special cases:
       
   121      * <ul><li>If the argument value is already equal to a mathematical integer,
       
   122      * then the result is the same as the argument.  <li>If the argument is NaN
       
   123      * or an infinity or positive zero or negative zero, then the result is the
       
   124      * same as the argument.</ul>
       
   125      *
       
   126      * @param a a value.
       
   127      * @return the largest (closest to positive infinity) floating-point value
       
   128      * that less than or equal to the argument and is equal to a mathematical
       
   129      * integer.
       
   130      */
       
   131     public static float floor_f(final float a) {
       
   132         // Derived from StrictMath.floor(double):
       
   133 
       
   134         // Inline call to Math.getExponent(a) to
       
   135         // compute only once Float.floatToRawIntBits(a)
       
   136         final int doppel = Float.floatToRawIntBits(a);
       
   137 
       
   138         final int exponent = ((doppel & FloatConsts.EXP_BIT_MASK)
       
   139                 >> (FloatConsts.SIGNIFICAND_WIDTH - 1))
       
   140                 - FloatConsts.EXP_BIAS;
       
   141 
       
   142         if (exponent < 0) {
       
   143             /*
       
   144              * Absolute value of argument is less than 1.
       
   145              * floorOrceil(-0.0) => -0.0
       
   146              * floorOrceil(+0.0) => +0.0
       
   147              */
       
   148             return ((a == 0) ? a :
       
   149                     ( (a < 0f) ? -1f : 0f) );
       
   150         }
       
   151         if (CHECK_OVERFLOW && (exponent >= 23)) { // 52 for double
       
   152             /*
       
   153              * Infinity, NaN, or a value so large it must be integral.
       
   154              */
       
   155             return a;
       
   156         }
       
   157         // Else the argument is either an integral value already XOR it
       
   158         // has to be rounded to one.
       
   159         assert exponent >= 0 && exponent <= 22; // 51 for double
       
   160 
       
   161         final int intpart = doppel
       
   162                 & (~(FloatConsts.SIGNIF_BIT_MASK >> exponent));
       
   163 
       
   164         if (intpart == doppel) {
       
   165             return a; // integral value (including 0)
       
   166         }
       
   167 
       
   168         // 0 handled above as an integer
       
   169         // sign: 1 for negative, 0 for positive numbers
       
   170         // add : -1 for negative and 0 for positive numbers
       
   171         return Float.intBitsToFloat(intpart) + (intpart >> 31);
       
   172     }
       
   173 
       
   174     /**
       
   175      * Faster alternative to ceil(float) optimized for the integer domain
       
   176      * and supporting NaN and +/-Infinity.
       
   177      *
       
   178      * @param a a value.
       
   179      * @return the largest (closest to positive infinity) integer value
       
   180      * that less than or equal to the argument and is equal to a mathematical
       
   181      * integer.
       
   182      */
       
   183     public static int ceil_int(final float a) {
       
   184         final int intpart = (int) a;
       
   185 
       
   186         if (a <= intpart
       
   187                 || (CHECK_OVERFLOW && intpart == Integer.MAX_VALUE)
       
   188                 || CHECK_NAN && Float.isNaN(a)) {
       
   189             return intpart;
       
   190         }
       
   191         return intpart + 1;
       
   192     }
       
   193 
       
   194     /**
       
   195      * Faster alternative to floor(float) optimized for the integer domain
       
   196      * and supporting NaN and +/-Infinity.
       
   197      *
       
   198      * @param a a value.
       
   199      * @return the largest (closest to positive infinity) floating-point value
       
   200      * that less than or equal to the argument and is equal to a mathematical
       
   201      * integer.
       
   202      */
       
   203     public static int floor_int(final float a) {
       
   204         final int intpart = (int) a;
       
   205 
       
   206         if (a >= intpart
       
   207                 || (CHECK_OVERFLOW && intpart == Integer.MIN_VALUE)
       
   208                 || CHECK_NAN && Float.isNaN(a)) {
       
   209             return intpart;
       
   210         }
       
   211         return intpart - 1;
       
   212     }
       
   213 
       
   214     /**
       
   215      * Returns a floating-point power of two in the normal range.
       
   216      */
       
   217     static double powerOfTwoD(int n) {
       
   218         assert (n >= DoubleConsts.MIN_EXPONENT && n <= DoubleConsts.MAX_EXPONENT);
       
   219         return Double.longBitsToDouble((((long) n + (long) DoubleConsts.EXP_BIAS)
       
   220                 << (DoubleConsts.SIGNIFICAND_WIDTH - 1))
       
   221                 & DoubleConsts.EXP_BIT_MASK);
       
   222     }
       
   223 }