Path: blob/master/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java
41159 views
/*1* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.marlin;2627/**28* Faster Math ceil / floor routines derived from StrictMath29*/30public final class FloatMath implements MarlinConst {3132// overflow / NaN handling enabled:33static final boolean CHECK_OVERFLOW = true;34static final boolean CHECK_NAN = true;35// Copied from sun.misc.FloatConsts:36public static final int FLOAT_SIGNIFICAND_WIDTH = 24; // sun.misc.FloatConsts.SIGNIFICAND_WIDTH37public static final int FLOAT_EXP_BIAS = 127; // sun.misc.FloatConsts.EXP_BIAS38public static final int FLOAT_EXP_BIT_MASK = 2139095040;// sun.misc.FloatConsts.EXP_BIT_MASK39public static final int FLOAT_SIGNIF_BIT_MASK = 8388607;// sun.misc.FloatConsts.SIGNIF_BIT_MASK4041private FloatMath() {42// utility class43}4445// faster inlined min/max functions in the branch prediction is high46static int max(final int a, final int b) {47return (a >= b) ? a : b;48}4950static int min(final int a, final int b) {51return (a <= b) ? a : b;52}5354/**55* Returns the smallest (closest to negative infinity) {@code float} value56* that is greater than or equal to the argument and is equal to a57* mathematical integer. Special cases:58* <ul><li>If the argument value is already equal to a mathematical integer,59* then the result is the same as the argument. <li>If the argument is NaN60* or an infinity or positive zero or negative zero, then the result is the61* same as the argument. <li>If the argument value is less than zero but62* greater than -1.0, then the result is negative zero.</ul> Note that the63* value of {@code StrictMath.ceil(x)} is exactly the value of64* {@code -StrictMath.floor(-x)}.65*66* @param a a value.67* @return the smallest (closest to negative infinity) floating-point value68* that is greater than or equal to the argument and is equal to a69* mathematical integer.70*/71public static float ceil_f(final float a) {72// Derived from StrictMath.ceil(double):7374// Inline call to Math.getExponent(a) to75// compute only once Float.floatToRawIntBits(a)76final int doppel = Float.floatToRawIntBits(a);7778final int exponent = ((doppel & FLOAT_EXP_BIT_MASK)79>> (FLOAT_SIGNIFICAND_WIDTH - 1))80- FLOAT_EXP_BIAS;8182if (exponent < 0) {83/*84* Absolute value of argument is less than 1.85* floorOrceil(-0.0) => -0.086* floorOrceil(+0.0) => +0.087*/88return ((a == 0.0f) ? a :89( (a < 0.0f) ? -0.0f : 1.0f) );90}91if (CHECK_OVERFLOW && (exponent >= 23)) { // 52 for double92/*93* Infinity, NaN, or a value so large it must be integral.94*/95return a;96}97// Else the argument is either an integral value already XOR it98// has to be rounded to one.99assert exponent >= 0 && exponent <= 22; // 51 for double100101final int intpart = doppel102& (~(FLOAT_SIGNIF_BIT_MASK >> exponent));103104if (intpart == doppel) {105return a; // integral value (including 0)106}107108// 0 handled above as an integer109// sign: 1 for negative, 0 for positive numbers110// add : 0 for negative and 1 for positive numbers111return Float.intBitsToFloat(intpart) + ((~intpart) >>> 31);112}113114/**115* Returns the largest (closest to positive infinity) {@code float} value116* that is less than or equal to the argument and is equal to a mathematical117* integer. Special cases:118* <ul><li>If the argument value is already equal to a mathematical integer,119* then the result is the same as the argument. <li>If the argument is NaN120* or an infinity or positive zero or negative zero, then the result is the121* same as the argument.</ul>122*123* @param a a value.124* @return the largest (closest to positive infinity) floating-point value125* that less than or equal to the argument and is equal to a mathematical126* integer.127*/128public static float floor_f(final float a) {129// Derived from StrictMath.floor(double):130131// Inline call to Math.getExponent(a) to132// compute only once Float.floatToRawIntBits(a)133final int doppel = Float.floatToRawIntBits(a);134135final int exponent = ((doppel & FLOAT_EXP_BIT_MASK)136>> (FLOAT_SIGNIFICAND_WIDTH - 1))137- FLOAT_EXP_BIAS;138139if (exponent < 0) {140/*141* Absolute value of argument is less than 1.142* floorOrceil(-0.0) => -0.0143* floorOrceil(+0.0) => +0.0144*/145return ((a == 0.0f) ? a :146( (a < 0.0f) ? -1.0f : 0.0f) );147}148if (CHECK_OVERFLOW && (exponent >= 23)) { // 52 for double149/*150* Infinity, NaN, or a value so large it must be integral.151*/152return a;153}154// Else the argument is either an integral value already XOR it155// has to be rounded to one.156assert exponent >= 0 && exponent <= 22; // 51 for double157158final int intpart = doppel159& (~(FLOAT_SIGNIF_BIT_MASK >> exponent));160161if (intpart == doppel) {162return a; // integral value (including 0)163}164165// 0 handled above as an integer166// sign: 1 for negative, 0 for positive numbers167// add : -1 for negative and 0 for positive numbers168return Float.intBitsToFloat(intpart) + (intpart >> 31);169}170171/**172* Faster alternative to ceil(float) optimized for the integer domain173* and supporting NaN and +/-Infinity.174*175* @param a a value.176* @return the largest (closest to positive infinity) integer value177* that less than or equal to the argument and is equal to a mathematical178* integer.179*/180public static int ceil_int(final float a) {181final int intpart = (int) a;182183if (a <= intpart184|| (CHECK_OVERFLOW && intpart == Integer.MAX_VALUE)185|| CHECK_NAN && Float.isNaN(a)) {186return intpart;187}188return intpart + 1;189}190191/**192* Faster alternative to ceil(double) optimized for the integer domain193* and supporting NaN and +/-Infinity.194*195* @param a a value.196* @return the largest (closest to positive infinity) integer value197* that less than or equal to the argument and is equal to a mathematical198* integer.199*/200public static int ceil_int(final double a) {201final int intpart = (int) a;202203if (a <= intpart204|| (CHECK_OVERFLOW && intpart == Integer.MAX_VALUE)205|| CHECK_NAN && Double.isNaN(a)) {206return intpart;207}208return intpart + 1;209}210211/**212* Faster alternative to floor(float) optimized for the integer domain213* and supporting NaN and +/-Infinity.214*215* @param a a value.216* @return the largest (closest to positive infinity) floating-point value217* that less than or equal to the argument and is equal to a mathematical218* integer.219*/220public static int floor_int(final float a) {221final int intpart = (int) a;222223if (a >= intpart224|| (CHECK_OVERFLOW && intpart == Integer.MIN_VALUE)225|| CHECK_NAN && Float.isNaN(a)) {226return intpart;227}228return intpart - 1;229}230231/**232* Faster alternative to floor(double) optimized for the integer domain233* and supporting NaN and +/-Infinity.234*235* @param a a value.236* @return the largest (closest to positive infinity) floating-point value237* that less than or equal to the argument and is equal to a mathematical238* integer.239*/240public static int floor_int(final double a) {241final int intpart = (int) a;242243if (a >= intpart244|| (CHECK_OVERFLOW && intpart == Integer.MIN_VALUE)245|| CHECK_NAN && Double.isNaN(a)) {246return intpart;247}248return intpart - 1;249}250}251252253