/** * Returns unbiased exponent of a <code>float</code>. */ public static int getExponent(float f){ /* * Bitwise convert f to integer, mask out exponent bits, shift * to the right and then subtract out float's bias adjust to * get true exponent value */ return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >> (FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS; }
/** * Returns a floating-point power of two in the normal range. */ static float powerOfTwoF(int n) { assert(n >= FloatConsts.MIN_EXPONENT && n <= FloatConsts.MAX_EXPONENT); return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) << (FloatConsts.SIGNIFICAND_WIDTH-1)) & FloatConsts.EXP_BIT_MASK); }
/** * Returns the closest {@code int} to the argument, with ties * rounding to positive infinity. * * <p> * Special cases: * <ul><li>If the argument is NaN, the result is 0. * <li>If the argument is negative infinity or any value less than or * equal to the value of {@code Integer.MIN_VALUE}, the result is * equal to the value of {@code Integer.MIN_VALUE}. * <li>If the argument is positive infinity or any value greater than or * equal to the value of {@code Integer.MAX_VALUE}, the result is * equal to the value of {@code Integer.MAX_VALUE}.</ul> * * @param a a floating-point value to be rounded to an integer. * @return the value of the argument rounded to the nearest * {@code int} value. * @see java.lang.Integer#MAX_VALUE * @see java.lang.Integer#MIN_VALUE */ public static int round(float a) { int intBits = Float.floatToRawIntBits(a); int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK) >> (FloatConsts.SIGNIFICAND_WIDTH - 1); int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2 + FloatConsts.EXP_BIAS) - biasedExp; if ((shift & -32) == 0) { // shift >= 0 && shift < 32 // a is a finite number such that pow(2,-32) <= ulp(a) < 1 int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK) | (FloatConsts.SIGNIF_BIT_MASK + 1)); if (intBits < 0) { r = -r; } // In the comments below each Java expression evaluates to the value // the corresponding mathematical expression: // (r) evaluates to a / ulp(a) // (r >> shift) evaluates to floor(a * 2) // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2) // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2) return ((r >> shift) + 1) >> 1; } else { // a is either // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2 // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer // - an infinity or NaN return (int) a; } }
public static int testFloatNextUp() { int failures=0; /* * Each row of testCases represents one test case for nextUp; * the first column is the input and the second column is the * expected result. */ float testCases [][] = { {NaNf, NaNf}, {-infinityF, -Float.MAX_VALUE}, {-Float.MAX_VALUE, -Float_MAX_VALUEmm}, {-FloatConsts.MIN_NORMAL, -Float_MAX_SUBNORMAL}, {-Float_MAX_SUBNORMAL, -Float_MAX_SUBNORMALmm}, {-Float.MIN_VALUE, -0.0f}, {-0.0f, Float.MIN_VALUE}, {+0.0f, Float.MIN_VALUE}, {Float.MIN_VALUE, Float.MIN_VALUE*2}, {Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMAL}, {Float_MAX_SUBNORMAL, FloatConsts.MIN_NORMAL}, {FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL+Float.MIN_VALUE}, {Float_MAX_VALUEmm, Float.MAX_VALUE}, {Float.MAX_VALUE, infinityF}, {infinityF, infinityF} }; for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.nextUp(float)", testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]); failures+=Tests.test("StrictMath.nextUp(float)", testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]); } return failures; }
public static int testFloatNextDown() { int failures=0; /* * Each row of testCases represents one test case for nextDown; * the first column is the input and the second column is the * expected result. */ float testCases [][] = { {NaNf, NaNf}, {-infinityF, -infinityF}, {-Float.MAX_VALUE, -infinityF}, {-Float_MAX_VALUEmm, -Float.MAX_VALUE}, {-Float_MAX_SUBNORMAL, -FloatConsts.MIN_NORMAL}, {-Float_MAX_SUBNORMALmm, -Float_MAX_SUBNORMAL}, {-0.0f, -Float.MIN_VALUE}, {+0.0f, -Float.MIN_VALUE}, {Float.MIN_VALUE, 0.0f}, {Float.MIN_VALUE*2, Float.MIN_VALUE}, {Float_MAX_SUBNORMAL, Float_MAX_SUBNORMALmm}, {FloatConsts.MIN_NORMAL, Float_MAX_SUBNORMAL}, {FloatConsts.MIN_NORMAL+ Float.MIN_VALUE, FloatConsts.MIN_NORMAL}, {Float.MAX_VALUE, Float_MAX_VALUEmm}, {infinityF, Float.MAX_VALUE}, }; for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.nextDown(float)", testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]); failures+=Tests.test("StrictMath.nextDown(float)", testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]); } return failures; }
public static int testFloatSignum() { int failures = 0; float testCases [][] = { {NaNf, NaNf}, {-infinityF, -1.0f}, {-Float.MAX_VALUE, -1.0f}, {-FloatConsts.MIN_NORMAL, -1.0f}, {-1.0f, -1.0f}, {-2.0f, -1.0f}, {-Float_MAX_SUBNORMAL, -1.0f}, {-Float.MIN_VALUE, -1.0f}, {-0.0f, -0.0f}, {+0.0f, +0.0f}, {Float.MIN_VALUE, 1.0f}, {Float_MAX_SUBNORMALmm, 1.0f}, {Float_MAX_SUBNORMAL, 1.0f}, {FloatConsts.MIN_NORMAL, 1.0f}, {1.0f, 1.0f}, {2.0f, 1.0f}, {Float_MAX_VALUEmm, 1.0f}, {Float.MAX_VALUE, 1.0f}, {infinityF, 1.0f} }; for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.signum(float)", testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]); failures+=Tests.test("StrictMath.signum(float)", testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]); } return failures; }
/** * Returns unbiased exponent of a {@code float}. */ public static int getExponent(float f){ /* * Bitwise convert f to integer, mask out exponent bits, shift * to the right and then subtract out float's bias adjust to * get true exponent value */ return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >> (FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS; }
public static int testFloatNextDown() { int failures=0; /* * Each row of testCases represents one test case for nextDown; * the first column is the input and the second column is the * expected result. */ float testCases [][] = { {NaNf, NaNf}, {-infinityF, -infinityF}, {-Float.MAX_VALUE, -infinityF}, {-Float_MAX_VALUEmm, -Float.MAX_VALUE}, {-Float_MAX_SUBNORMAL, -FloatConsts.MIN_NORMAL}, {-Float_MAX_SUBNORMALmm, -Float_MAX_SUBNORMAL}, {-0.0f, -Float.MIN_VALUE}, {+0.0f, -Float.MIN_VALUE}, {Float.MIN_VALUE, 0.0f}, {Float.MIN_VALUE*2, Float.MIN_VALUE}, {Float_MAX_SUBNORMAL, Float_MAX_SUBNORMALmm}, {FloatConsts.MIN_NORMAL, Float_MAX_SUBNORMAL}, {FloatConsts.MIN_NORMAL+ Float.MIN_VALUE, FloatConsts.MIN_NORMAL}, {Float.MAX_VALUE, Float_MAX_VALUEmm}, {infinityF, Float.MAX_VALUE}, }; for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("FpUtils.nextDown(float)", testCases[i][0], FpUtils.nextDown(testCases[i][0]), testCases[i][1]); } return failures; }