/* * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/* * Shared static test methods for numerical tests. Sharing these * helper test methods avoids repeated functions in the various test * programs. The test methods return 1 for a test failure and 0 for * success. The order of arguments to the test methods is generally * the test name, followed by the test arguments, the computed result, * and finally the expected result.
*/
publicclass Tests { private Tests(){}; // do not instantiate
/** * Return the floating-point value next larger in magnitude.
*/ publicstaticdouble nextOut(double d) { if (d > 0.0) return Math.nextUp(d); else return -Math.nextUp(-d);
}
/** * Returns unbiased exponent of a {@code float}; for * subnormal values, the number is treated as if it were * normalized. That is for all finite, non-zero, positive numbers * <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is * always in the range [1, 2). * <p> * Special cases: * <ul> * <li> If the argument is NaN, then the result is 2<sup>30</sup>. * <li> If the argument is infinite, then the result is 2<sup>28</sup>. * <li> If the argument is zero, then the result is -(2<sup>28</sup>). * </ul> * * @param f floating-point number whose exponent is to be extracted * @return unbiased exponent of the argument.
*/ publicstaticint ilogb(double d) { int exponent = Math.getExponent(d);
switch (exponent) { caseDouble.MAX_EXPONENT+1: // NaN or infinity if( Double.isNaN(d) ) return (1<<30); // 2^30 else// infinite value return (1<<28); // 2^28
caseDouble.MIN_EXPONENT-1: // zero or subnormal if(d == 0.0) { return -(1<<28); // -(2^28)
} else { long transducer = Double.doubleToRawLongBits(d);
/* * To avoid causing slow arithmetic on subnormals, * the scaling to determine when d's significand * is normalized is done in integer arithmetic. * (there must be at least one "1" bit in the * significand since zero has been screened out.
*/
// This loop is simple and functional. We might be // able to do something more clever that was faster; // e.g. number of leading zero detection on // (transducer << (# exponent and sign bits). while (transducer <
(1L << (DoubleConsts.SIGNIFICAND_WIDTH - 1))) {
transducer *= 2;
exponent--;
}
exponent++; assert( exponent >= Double.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1) &&
exponent < Double.MIN_EXPONENT); return exponent;
}
/** * Returns unbiased exponent of a {@code float}; for * subnormal values, the number is treated as if it were * normalized. That is for all finite, non-zero, positive numbers * <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is * always in the range [1, 2). * <p> * Special cases: * <ul> * <li> If the argument is NaN, then the result is 2<sup>30</sup>. * <li> If the argument is infinite, then the result is 2<sup>28</sup>. * <li> If the argument is zero, then the result is -(2<sup>28</sup>). * </ul> * * @param f floating-point number whose exponent is to be extracted * @return unbiased exponent of the argument.
*/ publicstaticint ilogb(float f) { int exponent = Math.getExponent(f);
switch (exponent) { caseFloat.MAX_EXPONENT+1: // NaN or infinity if( Float.isNaN(f) ) return (1<<30); // 2^30 else// infinite value return (1<<28); // 2^28
caseFloat.MIN_EXPONENT-1: // zero or subnormal if(f == 0.0f) { return -(1<<28); // -(2^28)
} else { int transducer = Float.floatToRawIntBits(f);
/* * To avoid causing slow arithmetic on subnormals, * the scaling to determine when f's significand * is normalized is done in integer arithmetic. * (there must be at least one "1" bit in the * significand since zero has been screened out.
*/
// This loop is simple and functional. We might be // able to do something more clever that was faster; // e.g. number of leading zero detection on // (transducer << (# exponent and sign bits). while (transducer <
(1 << (FloatConsts.SIGNIFICAND_WIDTH - 1))) {
transducer *= 2;
exponent--;
}
exponent++; assert( exponent >= Float.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1) &&
exponent < Float.MIN_EXPONENT); return exponent;
}
/** * Returns {@code true} if the unordered relation holds * between the two arguments. When two floating-point values are * unordered, one value is neither less than, equal to, nor * greater than the other. For the unordered relation to be true, * at least one argument must be a {@code NaN}. * * @param arg1 the first argument * @param arg2 the second argument * @return {@code true} if at least one argument is a NaN, * {@code false} otherwise.
*/ publicstaticboolean isUnordered(float arg1, float arg2) { returnFloat.isNaN(arg1) || Float.isNaN(arg2);
}
/** * Returns {@code true} if the unordered relation holds * between the two arguments. When two floating-point values are * unordered, one value is neither less than, equal to, nor * greater than the other. For the unordered relation to be true, * at least one argument must be a {@code NaN}. * * @param arg1 the first argument * @param arg2 the second argument * @return {@code true} if at least one argument is a NaN, * {@code false} otherwise.
*/ publicstaticboolean isUnordered(double arg1, double arg2) { returnDouble.isNaN(arg1) || Double.isNaN(arg2);
}
staticint testUlpCore(double result, double expected, double ulps) { // We assume we won't be unlucky and have an inexact expected // be nextDown(2^i) when 2^i would be the correctly rounded // answer. This would cause the ulp size to be half as large // as it should be, doubling the measured error).
if (Double.compare(expected, result) == 0) { return 0; // result and expected are equivalent
} else { if( ulps == 0.0) { // Equivalent results required but not found return 1;
} else { double difference = expected - result; if (isUnordered(expected, result) || Double.isNaN(difference) || // fail if greater than or unordered
!(Math.abs( difference/Math.ulp(expected) ) <= Math.abs(ulps)) ) { return 1;
} else { return 0;
}
}
}
}
// For a successful test, the result must be within the ulp bound of // expected AND the result must have absolute value less than or // equal to absBound. publicstaticint testUlpDiffWithAbsBound(String testName, double input,
DoubleUnaryOperator func, double expected, double ulps, double absBound) { return testUlpDiffWithAbsBound(testName, input,
func.applyAsDouble(input), expected,
ulps, absBound);
}
if (code == 1) {
System.err.println("Failure for " + testName + ":\n" + "\tFor input " + input + "\t(" + toHexString(input) + ")\n" + "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ");\n" + "\tdifference greater than ulp tolerance " + ulps + " or the result has larger magnitude than " + absBound);
} return code;
}
// For a successful test, the result must be within the ulp bound of // expected AND the result must have absolute value greater than // or equal to the lowerBound. publicstaticint testUlpDiffWithLowerBound(String testName, double input,
DoubleUnaryOperator func, double expected, double ulps, double lowerBound) { return testUlpDiffWithLowerBound(testName, input,
func.applyAsDouble(input), expected,
ulps, lowerBound);
}
// For a successful test, the result must be within the upper and // lower bounds. publicstaticint testBounds(String testName, double input, DoubleUnaryOperator func, double bound1, double bound2) { return testBounds(testName, input, func.applyAsDouble(input), bound1, bound2);
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.4Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.