/** * Returns unbiased exponent of a <code>double</code>. */ public static int getExponent(double d){ /* * Bitwise convert d to long, mask out exponent bits, shift * to the right and then subtract out double's bias adjust to * get true exponent value. */ return (int)(((Double.doubleToRawLongBits(d) & DoubleConsts.EXP_BIT_MASK) >> (DoubleConsts.SIGNIFICAND_WIDTH - 1)) - DoubleConsts.EXP_BIAS); }
/** * Returns a floating-point power of two in the normal range. */ static double powerOfTwoD(int n) { assert(n >= DoubleConsts.MIN_EXPONENT && n <= DoubleConsts.MAX_EXPONENT); return Double.longBitsToDouble((((long)n + (long)DoubleConsts.EXP_BIAS) << (DoubleConsts.SIGNIFICAND_WIDTH-1)) & DoubleConsts.EXP_BIT_MASK); }
/** * Returns the closest {@code long} 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 Long.MIN_VALUE}, the result is * equal to the value of {@code Long.MIN_VALUE}. * <li>If the argument is positive infinity or any value greater than or * equal to the value of {@code Long.MAX_VALUE}, the result is * equal to the value of {@code Long.MAX_VALUE}.</ul> * * @param a a floating-point value to be rounded to a * {@code long}. * @return the value of the argument rounded to the nearest * {@code long} value. * @see java.lang.Long#MAX_VALUE * @see java.lang.Long#MIN_VALUE */ public static long round(double a) { long longBits = Double.doubleToRawLongBits(a); long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK) >> (DoubleConsts.SIGNIFICAND_WIDTH - 1); long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2 + DoubleConsts.EXP_BIAS) - biasedExp; if ((shift & -64) == 0) { // shift >= 0 && shift < 64 // a is a finite number such that pow(2,-64) <= ulp(a) < 1 long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK) | (DoubleConsts.SIGNIF_BIT_MASK + 1)); if (longBits < 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,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2 // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer // - an infinity or NaN return (long) a; } }
public static int testDoubleNextUp() { 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. */ double testCases [][] = { {NaNd, NaNd}, {-infinityD, -Double.MAX_VALUE}, {-Double.MAX_VALUE, -Double_MAX_VALUEmm}, {-DoubleConsts.MIN_NORMAL, -Double_MAX_SUBNORMAL}, {-Double_MAX_SUBNORMAL, -Double_MAX_SUBNORMALmm}, {-Double.MIN_VALUE, -0.0d}, {-0.0d, Double.MIN_VALUE}, {+0.0d, Double.MIN_VALUE}, {Double.MIN_VALUE, Double.MIN_VALUE*2}, {Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMAL}, {Double_MAX_SUBNORMAL, DoubleConsts.MIN_NORMAL}, {DoubleConsts.MIN_NORMAL, DoubleConsts.MIN_NORMAL+Double.MIN_VALUE}, {Double_MAX_VALUEmm, Double.MAX_VALUE}, {Double.MAX_VALUE, infinityD}, {infinityD, infinityD} }; for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.nextUp(double)", testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]); failures+=Tests.test("StrictMath.nextUp(double)", testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]); } return failures; }
public static int testDoubleNextDown() { 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. */ double testCases [][] = { {NaNd, NaNd}, {-infinityD, -infinityD}, {-Double.MAX_VALUE, -infinityD}, {-Double_MAX_VALUEmm, -Double.MAX_VALUE}, {-Double_MAX_SUBNORMAL, -DoubleConsts.MIN_NORMAL}, {-Double_MAX_SUBNORMALmm, -Double_MAX_SUBNORMAL}, {-0.0d, -Double.MIN_VALUE}, {+0.0d, -Double.MIN_VALUE}, {Double.MIN_VALUE, 0.0d}, {Double.MIN_VALUE*2, Double.MIN_VALUE}, {Double_MAX_SUBNORMAL, Double_MAX_SUBNORMALmm}, {DoubleConsts.MIN_NORMAL, Double_MAX_SUBNORMAL}, {DoubleConsts.MIN_NORMAL+ Double.MIN_VALUE, DoubleConsts.MIN_NORMAL}, {Double.MAX_VALUE, Double_MAX_VALUEmm}, {infinityD, Double.MAX_VALUE}, }; for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.nextDown(double)", testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]); failures+=Tests.test("StrictMath.nextDown(double)", testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]); } return failures; }
public static int testDoubleSignum() { int failures = 0; double testCases [][] = { {NaNd, NaNd}, {-infinityD, -1.0}, {-Double.MAX_VALUE, -1.0}, {-DoubleConsts.MIN_NORMAL, -1.0}, {-1.0, -1.0}, {-2.0, -1.0}, {-Double_MAX_SUBNORMAL, -1.0}, {-Double.MIN_VALUE, -1.0d}, {-0.0d, -0.0d}, {+0.0d, +0.0d}, {Double.MIN_VALUE, 1.0}, {Double_MAX_SUBNORMALmm, 1.0}, {Double_MAX_SUBNORMAL, 1.0}, {DoubleConsts.MIN_NORMAL, 1.0}, {1.0, 1.0}, {2.0, 1.0}, {Double_MAX_VALUEmm, 1.0}, {Double.MAX_VALUE, 1.0}, {infinityD, 1.0} }; for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.signum(double)", testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]); failures+=Tests.test("StrictMath.signum(double)", testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]); } return failures; }
/** * Returns unbiased exponent of a {@code double}. */ public static int getExponent(double d){ /* * Bitwise convert d to long, mask out exponent bits, shift * to the right and then subtract out double's bias adjust to * get true exponent value. */ return (int)(((Double.doubleToRawLongBits(d) & DoubleConsts.EXP_BIT_MASK) >> (DoubleConsts.SIGNIFICAND_WIDTH - 1)) - DoubleConsts.EXP_BIAS); }
public static int testDoubleNextDown() { 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. */ double testCases [][] = { {NaNd, NaNd}, {-infinityD, -infinityD}, {-Double.MAX_VALUE, -infinityD}, {-Double_MAX_VALUEmm, -Double.MAX_VALUE}, {-Double_MAX_SUBNORMAL, -DoubleConsts.MIN_NORMAL}, {-Double_MAX_SUBNORMALmm, -Double_MAX_SUBNORMAL}, {-0.0d, -Double.MIN_VALUE}, {+0.0d, -Double.MIN_VALUE}, {Double.MIN_VALUE, 0.0d}, {Double.MIN_VALUE*2, Double.MIN_VALUE}, {Double_MAX_SUBNORMAL, Double_MAX_SUBNORMALmm}, {DoubleConsts.MIN_NORMAL, Double_MAX_SUBNORMAL}, {DoubleConsts.MIN_NORMAL+ Double.MIN_VALUE, DoubleConsts.MIN_NORMAL}, {Double.MAX_VALUE, Double_MAX_VALUEmm}, {infinityD, Double.MAX_VALUE}, }; for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("FpUtils.nextDown(double)", testCases[i][0], FpUtils.nextDown(testCases[i][0]), testCases[i][1]); } return failures; }