/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/*
* @test
* @bug 4860891 4826732 4780454 4939441 4826652
* @summary Tests for IEEE 754[R] recommended functions and similar methods
* @author Joseph D. Darcy
*/
public class IeeeRecommendedTests {
private IeeeRecommendedTests(){}
// Initialize shared random number generator
/**
* Returns a floating-point power of two in the normal range.
*/
static double powerOfTwoD(int n) {
}
/**
* Returns a floating-point power of two in the normal range.
*/
static float powerOfTwoF(int n) {
}
/* ******************** getExponent tests ****************************** */
/*
* The tests for getExponent should test the special values (NaN, +/-
* infinity, etc.), test the endpoints of each binade (set of
* floating-point values with the same exponent), and for good
* measure, test some random values within each binade. Testing
* the endpoints of each binade includes testing both positive and
* negative numbers. Subnormal values with different normalized
* exponents should be tested too. Both Math and StrictMath
* methods should return the same results.
*/
/*
* Test Math.getExponent and StrictMath.getExponent with +d and -d.
*/
float minus_f = -f;
int failures=0;
return failures;
}
/*
* Test Math.getExponent and StrictMath.getExponent with +d and -d.
*/
double minus_d = -d;
int failures=0;
return failures;
}
public static int testFloatGetExponent() {
int failures = 0;
float [] specialValues = {NaNf,
+0.0f,
+1.0f,
+2.0f,
+16.0f,
};
0,
1,
4,
};
// Special value tests
}
// Normal exponent tests
int result;
// Create power of two
float po2 = powerOfTwoF(i);
// Generate some random bit patterns for the significand
for(int j = 0; j < 10; j++) {
float randFloat;
(~FloatConsts.SIGNIF_BIT_MASK)) |
// Significand
(randSignif &
}
if (i > FloatConsts.MIN_EXPONENT) {
}
}
// Subnormal exponent tests
/*
* Start with MIN_VALUE, left shift, test high value, low
* values, and random in between.
*
* Use nextAfter to calculate, high value of previous binade,
* loop count i will indicate how many random bits, if any are
* needed.
*/
for( int i = 1;
i++, top *= 2.0f) {
// Test largest value in next smaller binade
if (i >= 3) {// (i == 1) would test 0.0;
// (i == 2) would just retest MIN_VALUE
if( i >= 10) {
// create a bit mask with (i-1) 1's in the low order
// bits
// Significand
}
}
}
return failures;
}
public static int testDoubleGetExponent() {
int failures = 0;
double [] specialValues = {NaNd,
+0.0,
+1.0,
+2.0,
+16.0,
};
0,
1,
4,
};
// Special value tests
}
// Normal exponent tests
int result;
// Create power of two
double po2 = powerOfTwoD(i);
// Generate some random bit patterns for the significand
for(int j = 0; j < 10; j++) {
double randFloat;
(~DoubleConsts.SIGNIF_BIT_MASK)) |
// Significand
(randSignif &
}
if (i > DoubleConsts.MIN_EXPONENT) {
}
}
// Subnormal exponent tests
/*
* Start with MIN_VALUE, left shift, test high value, low
* values, and random in between.
*
* Use nextAfter to calculate, high value of previous binade;
* loop count i will indicate how many random bits, if any are
* needed.
*/
for( int i = 1;
i++, top *= 2.0f) {
// Test largest value in next smaller binade
if (i >= 3) {// (i == 1) would test 0.0;
// (i == 2) would just retest MIN_VALUE
if( i >= 10) {
// create a bit mask with (i-1) 1's in the low order
// bits
// Significand
}
}
}
return failures;
}
/* ******************** nextAfter tests ****************************** */
int failures=0;
float minus_start = -start;
double minus_direction = -direction;
float minus_expected = -expected;
return failures;
}
int failures=0;
double minus_start = -start;
double minus_direction = -direction;
double minus_expected = -expected;
return failures;
}
public static int testFloatNextAfter() {
int failures=0;
/*
* Each row of the testCases matrix represents one test case
* for nexAfter; given the input of the first two columns, the
* result in the last column is expected.
*/
float [][] testCases = {
// Make sure zero behavior is tested
{0.0f, 0.0f, 0.0f},
{0.0f, -0.0f, -0.0f},
{-0.0f, 0.0f, 0.0f},
{-0.0f, -0.0f, -0.0f},
};
testCases[i][2]);
}
return failures;
}
public static int testDoubleNextAfter() {
int failures =0;
/*
* Each row of the testCases matrix represents one test case
* for nexAfter; given the input of the first two columns, the
* result in the last column is expected.
*/
double [][] testCases = {
// Make sure zero behavior is tested
{0.0d, 0.0d, 0.0d},
{0.0d, -0.0d, -0.0d},
{-0.0d, 0.0d, 0.0d},
{-0.0d, -0.0d, -0.0d},
};
testCases[i][2]);
}
return failures;
}
/* ******************** nextUp tests ********************************* */
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 [][] = {
};
}
return failures;
}
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 [][] = {
};
}
return failures;
}
/* ******************** nextDown tests ********************************* */
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 [][] = {
};
}
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 [][] = {
};
}
return failures;
}
/* ********************** boolean tests ****************************** */
/*
* Combined tests for boolean functions, isFinite, isInfinite,
* isNaN, isUnordered.
*/
public static int testFloatBooleanMethods() {
int failures = 0;
float testCases [] = {
NaNf,
-3.0f,
-1.0f,
-0.0f,
+0.0f,
1.0f,
3.0f,
};
// isNaN
// isFinite
// isInfinite
// isUnorderd
}
}
return failures;
}
public static int testDoubleBooleanMethods() {
int failures = 0;
boolean result = false;
double testCases [] = {
NaNd,
-3.0d,
-1.0d,
-0.0d,
+0.0d,
1.0d,
3.0d,
};
// isNaN
// isFinite
// isInfinite
// isUnorderd
}
}
return failures;
}
/* ******************** copySign tests******************************** */
public static int testFloatCopySign() {
int failures = 0;
// testCases[0] are logically positive numbers;
// testCases[1] are negative numbers.
float testCases [][] = {
{+0.0f,
1.0f,
3.0f,
},
{-infinityF,
-3.0f,
-1.0f,
-0.0f}
};
// Tests shared between raw and non-raw versions
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
// copySign(magnitude, sign)
}
}
}
}
// For rawCopySign, NaN may effectively have either sign bit
// while for copySign NaNs are treated as if they always have
// a zero sign bit (i.e. as positive numbers)
for(int i = 0; i < 2; i++) {
// copySign(magnitude, sign)
}
}
}
return failures;
}
public static int testDoubleCopySign() {
int failures = 0;
// testCases[0] are logically positive numbers;
// testCases[1] are negative numbers.
double testCases [][] = {
{+0.0d,
1.0d,
3.0d,
},
{-infinityD,
-3.0d,
-1.0d,
-0.0d}
};
// Tests shared between Math and StrictMath versions
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
// copySign(magnitude, sign)
}
}
}
}
// For Math.copySign, NaN may effectively have either sign bit
// while for StrictMath.copySign NaNs are treated as if they
// always have a zero sign bit (i.e. as positive numbers)
for(int i = 0; i < 2; i++) {
// copySign(magnitude, sign)
}
}
}
return failures;
}
/* ************************ scalb tests ******************************* */
int failures=0;
return failures;
}
public static int testFloatScalb() {
int failures=0;
// Arguments x, where scalb(x,n) is x for any n.
float [] identityTestCases = {NaNf,
-0.0f,
+0.0f,
};
float [] subnormalTestCases = {
};
float [] someTestCases = {
1.0f,
2.0f,
3.0f,
};
int [] oneMultiplyScalingFactors = {
-3,
-2,
-1,
0,
1,
2,
3,
};
int [] manyScalingFactors = {
-MAX_SCALE -1,
-MAX_SCALE+1,
-2,
-1,
0,
1,
2,
MAX_SCALE-1,
MAX_SCALE+1,
};
// Test cases where scaling is always a no-op
identityTestCases[i]);
}
}
// Test cases where result is 0.0 or infinity due to magnitude
// of the scaling factor
int scaleFactor = manyScalingFactors[j];
float value = someTestCases[i];
}
}
}
// Test cases that could be done with one floating-point
// multiply.
int scaleFactor = oneMultiplyScalingFactors[j];
float value = someTestCases[i];
}
}
// Create 2^MAX_EXPONENT
twoToTheMaxExp *=2.0f;
// Scale-up subnormal values until they all overflow
float value = subnormalTestCases[i];
int scaleFactor = j;
// calculate right answer
scale*=2.0f;
}
}
// Scale down a large number until it underflows. By scaling
// down MAX_NORMALmm, the first subnormal result will be exact
// but the next one will round -- all those results can be
// checked by halving a separate value in the loop. Actually,
// we can keep halving and checking until the product is zero
// since:
//
// 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
// it will round *up*
//
// 2. When rounding first occurs in the expected product, it
// too rounds up, to 2^-MAX_EXPONENT.
//
// Halving expected after rounding happends to give the same
// result as the scalb operation.
for(int i = -1; i > -MAX_SCALE; i--) {
expected *= 0.5f;
}
// Tricky rounding tests:
// Scale down a large number into subnormal range such that if
// scalb is being implemented with multiple floating-point
// multiplies, the value would round twice if the multiplies
// were done in the wrong order.
for(int i = 0; i < 129; i++) {
-127-i,
expected);
value *=2.0f;
}
return failures;
}
int failures=0;
return failures;
}
public static int testDoubleScalb() {
int failures=0;
// Arguments x, where scalb(x,n) is x for any n.
double [] identityTestCases = {NaNd,
-0.0,
+0.0,
};
double [] subnormalTestCases = {
};
double [] someTestCases = {
1.0d,
2.0d,
3.0d,
};
int [] oneMultiplyScalingFactors = {
-3,
-2,
-1,
0,
1,
2,
3,
};
int [] manyScalingFactors = {
-MAX_SCALE -1,
-MAX_SCALE+1,
-2,
-1,
0,
1,
2,
MAX_SCALE-1,
MAX_SCALE+1,
};
// Test cases where scaling is always a no-op
identityTestCases[i]);
}
}
// Test cases where result is 0.0 or infinity due to magnitude
// of the scaling factor
int scaleFactor = manyScalingFactors[j];
double value = someTestCases[i];
}
}
}
// Test cases that could be done with one floating-point
// multiply.
int scaleFactor = oneMultiplyScalingFactors[j];
double value = someTestCases[i];
}
}
// Create 2^MAX_EXPONENT
twoToTheMaxExp *=2.0;
// Scale-up subnormal values until they all overflow
double value = subnormalTestCases[i];
int scaleFactor = j;
// calculate right answer
scale*=2.0;
}
}
// Scale down a large number until it underflows. By scaling
// down MAX_NORMALmm, the first subnormal result will be exact
// but the next one will round -- all those results can be
// checked by halving a separate value in the loop. Actually,
// we can keep halving and checking until the product is zero
// since:
//
// 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
// it will round *up*
//
// 2. When rounding first occurs in the expected product, it
// too rounds up, to 2^-MAX_EXPONENT.
//
// Halving expected after rounding happends to give the same
// result as the scalb operation.
for(int i = -1; i > -MAX_SCALE; i--) {
expected *= 0.5;
}
// Tricky rounding tests:
// Scale down a large number into subnormal range such that if
// scalb is being implemented with multiple floating-point
// multiplies, the value would round twice if the multiplies
// were done in the wrong order.
-1024-i,
expected);
value *=2.0;
}
return failures;
}
/* ************************* ulp tests ******************************* */
/*
* Test Math.ulp and StrictMath.ulp with +d and -d.
*/
float minus_f = -f;
int failures=0;
return failures;
}
double minus_d = -d;
int failures=0;
return failures;
}
public static int testFloatUlp() {
int failures = 0;
float [] specialValues = {NaNf,
+0.0f,
+1.0f,
+2.0f,
+16.0f,
};
float [] specialResults = {NaNf,
powerOfTwoF(-23),
powerOfTwoF(-22),
powerOfTwoF(-19),
powerOfTwoF(104)
};
// Special value tests
}
// Normal exponent tests
float expected;
// Create power of two
float po2 = powerOfTwoF(i);
// Generate some random bit patterns for the significand
for(int j = 0; j < 10; j++) {
float randFloat;
(~FloatConsts.SIGNIF_BIT_MASK)) |
// Significand
(randSignif &
}
if (i > FloatConsts.MIN_EXPONENT) {
}
}
// Subnormal tests
/*
* Start with MIN_VALUE, left shift, test high value, low
* values, and random in between.
*
* Use nextAfter to calculate, high value of previous binade,
* loop count i will indicate how many random bits, if any are
* needed.
*/
for( int i = 1;
i++, top *= 2.0f) {
// Test largest value in next smaller binade
if (i >= 3) {// (i == 1) would test 0.0;
// (i == 2) would just retest MIN_VALUE
if( i >= 10) {
// create a bit mask with (i-1) 1's in the low order
// bits
// Significand
}
}
}
return failures;
}
public static int testDoubleUlp() {
int failures = 0;
double [] specialValues = {NaNd,
+0.0d,
+1.0d,
+2.0d,
+16.0d,
};
double [] specialResults = {NaNf,
powerOfTwoD(-52),
powerOfTwoD(-51),
powerOfTwoD(-48),
powerOfTwoD(971)
};
// Special value tests
}
// Normal exponent tests
double expected;
// Create power of two
double po2 = powerOfTwoD(i);
// Generate some random bit patterns for the significand
for(int j = 0; j < 10; j++) {
double randDouble;
(~DoubleConsts.SIGNIF_BIT_MASK)) |
// Significand
(randSignif &
}
if (i > DoubleConsts.MIN_EXPONENT) {
}
}
// Subnormal tests
/*
* Start with MIN_VALUE, left shift, test high value, low
* values, and random in between.
*
* Use nextAfter to calculate, high value of previous binade,
* loop count i will indicate how many random bits, if any are
* needed.
*/
for( int i = 1;
i++, top *= 2.0f) {
// Test largest value in next smaller binade
if (i >= 3) {// (i == 1) would test 0.0;
// (i == 2) would just retest MIN_VALUE
if( i >= 10) {
// create a bit mask with (i-1) 1's in the low order
// bits
// Significand
}
}
}
return failures;
}
public static int testFloatSignum() {
int failures = 0;
float testCases [][] = {
{-infinityF, -1.0f},
{-1.0f, -1.0f},
{-2.0f, -1.0f},
{-Float_MAX_SUBNORMAL, -1.0f},
{-0.0f, -0.0f},
{+0.0f, +0.0f},
{Float_MAX_SUBNORMALmm, 1.0f},
{Float_MAX_SUBNORMAL, 1.0f},
{1.0f, 1.0f},
{2.0f, 1.0f},
{Float_MAX_VALUEmm, 1.0f},
{infinityF, 1.0f}
};
}
return failures;
}
public static int testDoubleSignum() {
int failures = 0;
double testCases [][] = {
{-infinityD, -1.0},
{-1.0, -1.0},
{-2.0, -1.0},
{-Double_MAX_SUBNORMAL, -1.0},
{-0.0d, -0.0d},
{+0.0d, +0.0d},
{Double_MAX_SUBNORMALmm, 1.0},
{Double_MAX_SUBNORMAL, 1.0},
{1.0, 1.0},
{2.0, 1.0},
{Double_MAX_VALUEmm, 1.0},
{infinityD, 1.0}
};
}
return failures;
}
int failures = 0;
failures += testFloatGetExponent();
failures += testFloatNextAfter();
failures += testDoubleNextAfter();
failures += testFloatNextUp();
failures += testDoubleNextUp();
failures += testFloatNextDown();
failures += testDoubleNextDown();
failures += testFloatCopySign();
failures += testDoubleCopySign();
failures += testFloatScalb();
failures += testDoubleScalb();
failures += testFloatUlp();
failures += testDoubleUlp();
failures += testFloatSignum();
failures += testDoubleSignum();
if (failures > 0) {
+ failures + " failures.");
throw new RuntimeException();
}
}
}