Path: blob/master/test/jdk/java/lang/Math/IeeeRecommendedTests.java
41152 views
/*1* Copyright (c) 2003, 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.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @library /test/lib26* @build jdk.test.lib.RandomFactory27* @run main IeeeRecommendedTests28* @bug 4860891 4826732 4780454 4939441 4826652 807867229* @summary Tests for IEEE 754[R] recommended functions and similar methods (use -Dseed=X to set PRNG seed)30* @author Joseph D. Darcy31* @key randomness32*/3334import jdk.test.lib.RandomFactory;3536public class IeeeRecommendedTests {37private IeeeRecommendedTests(){}3839static final float NaNf = Float.NaN;40static final double NaNd = Double.NaN;41static final float infinityF = Float.POSITIVE_INFINITY;42static final double infinityD = Double.POSITIVE_INFINITY;4344static final float Float_MAX_VALUEmm = 0x1.fffffcP+127f;45static final float Float_MAX_SUBNORMAL = 0x0.fffffeP-126f;46static final float Float_MAX_SUBNORMALmm = 0x0.fffffcP-126f;4748static final double Double_MAX_VALUEmm = 0x1.ffffffffffffeP+1023;49static final double Double_MAX_SUBNORMAL = 0x0.fffffffffffffP-1022;50static final double Double_MAX_SUBNORMALmm = 0x0.ffffffffffffeP-1022;5152// Initialize shared random number generator53static java.util.Random rand = RandomFactory.getRandom();5455/**56* Returns a floating-point power of two in the normal range.57*/58static double powerOfTwoD(int n) {59return Double.longBitsToDouble((((long)n + (long)Double.MAX_EXPONENT) <<60(DoubleConsts.SIGNIFICAND_WIDTH-1))61& DoubleConsts.EXP_BIT_MASK);62}6364/**65* Returns a floating-point power of two in the normal range.66*/67static float powerOfTwoF(int n) {68return Float.intBitsToFloat(((n + Float.MAX_EXPONENT) <<69(FloatConsts.SIGNIFICAND_WIDTH-1))70& FloatConsts.EXP_BIT_MASK);71}7273/* ******************** getExponent tests ****************************** */7475/*76* The tests for getExponent should test the special values (NaN, +/-77* infinity, etc.), test the endpoints of each binade (set of78* floating-point values with the same exponent), and for good79* measure, test some random values within each binade. Testing80* the endpoints of each binade includes testing both positive and81* negative numbers. Subnormal values with different normalized82* exponents should be tested too. Both Math and StrictMath83* methods should return the same results.84*/8586/*87* Test Math.getExponent and StrictMath.getExponent with +d and -d.88*/89static int testGetExponentCase(float f, int expected) {90float minus_f = -f;91int failures=0;9293failures+=Tests.test("Math.getExponent(float)", f,94Math.getExponent(f), expected);95failures+=Tests.test("Math.getExponent(float)", minus_f,96Math.getExponent(minus_f), expected);9798failures+=Tests.test("StrictMath.getExponent(float)", f,99StrictMath.getExponent(f), expected);100failures+=Tests.test("StrictMath.getExponent(float)", minus_f,101StrictMath.getExponent(minus_f), expected);102return failures;103}104105/*106* Test Math.getExponent and StrictMath.getExponent with +d and -d.107*/108static int testGetExponentCase(double d, int expected) {109double minus_d = -d;110int failures=0;111112failures+=Tests.test("Math.getExponent(double)", d,113Math.getExponent(d), expected);114failures+=Tests.test("Math.getExponent(double)", minus_d,115Math.getExponent(minus_d), expected);116117failures+=Tests.test("StrictMath.getExponent(double)", d,118StrictMath.getExponent(d), expected);119failures+=Tests.test("StrictMath.getExponent(double)", minus_d,120StrictMath.getExponent(minus_d), expected);121return failures;122}123124public static int testFloatGetExponent() {125int failures = 0;126float [] specialValues = {NaNf,127Float.POSITIVE_INFINITY,128+0.0f,129+1.0f,130+2.0f,131+16.0f,132+Float.MIN_VALUE,133+Float_MAX_SUBNORMAL,134+Float.MIN_NORMAL,135+Float.MAX_VALUE136};137138int [] specialResults = {Float.MAX_EXPONENT + 1, // NaN results139Float.MAX_EXPONENT + 1, // Infinite results140Float.MIN_EXPONENT - 1, // Zero results1410,1421,1434,144Float.MIN_EXPONENT - 1,145-Float.MAX_EXPONENT,146Float.MIN_EXPONENT,147Float.MAX_EXPONENT148};149150// Special value tests151for(int i = 0; i < specialValues.length; i++) {152failures += testGetExponentCase(specialValues[i], specialResults[i]);153}154155156// Normal exponent tests157for(int i = Float.MIN_EXPONENT; i <= Float.MAX_EXPONENT; i++) {158int result;159160// Create power of two161float po2 = powerOfTwoF(i);162163failures += testGetExponentCase(po2, i);164165// Generate some random bit patterns for the significand166for(int j = 0; j < 10; j++) {167int randSignif = rand.nextInt();168float randFloat;169170randFloat = Float.intBitsToFloat( // Exponent171(Float.floatToIntBits(po2)&172(~FloatConsts.SIGNIF_BIT_MASK)) |173// Significand174(randSignif &175FloatConsts.SIGNIF_BIT_MASK) );176177failures += testGetExponentCase(randFloat, i);178}179180if (i > Float.MIN_EXPONENT) {181float po2minus = Math.nextAfter(po2,182Float.NEGATIVE_INFINITY);183failures += testGetExponentCase(po2minus, i-1);184}185}186187// Subnormal exponent tests188189/*190* Start with MIN_VALUE, left shift, test high value, low191* values, and random in between.192*193* Use nextAfter to calculate, high value of previous binade,194* loop count i will indicate how many random bits, if any are195* needed.196*/197198float top=Float.MIN_VALUE;199for( int i = 1;200i < FloatConsts.SIGNIFICAND_WIDTH;201i++, top *= 2.0f) {202203failures += testGetExponentCase(top,204Float.MIN_EXPONENT - 1);205206// Test largest value in next smaller binade207if (i >= 3) {// (i == 1) would test 0.0;208// (i == 2) would just retest MIN_VALUE209testGetExponentCase(Math.nextAfter(top, 0.0f),210Float.MIN_EXPONENT - 1);211212if( i >= 10) {213// create a bit mask with (i-1) 1's in the low order214// bits215int mask = ~((~0)<<(i-1));216float randFloat = Float.intBitsToFloat( // Exponent217Float.floatToIntBits(top) |218// Significand219(rand.nextInt() & mask ) ) ;220221failures += testGetExponentCase(randFloat,222Float.MIN_EXPONENT - 1);223}224}225}226227return failures;228}229230231public static int testDoubleGetExponent() {232int failures = 0;233double [] specialValues = {NaNd,234infinityD,235+0.0,236+1.0,237+2.0,238+16.0,239+Double.MIN_VALUE,240+Double_MAX_SUBNORMAL,241+Double.MIN_NORMAL,242+Double.MAX_VALUE243};244245int [] specialResults = {Double.MAX_EXPONENT + 1, // NaN results246Double.MAX_EXPONENT + 1, // Infinite results247Double.MIN_EXPONENT - 1, // Zero results2480,2491,2504,251Double.MIN_EXPONENT - 1,252-Double.MAX_EXPONENT,253Double.MIN_EXPONENT,254Double.MAX_EXPONENT255};256257// Special value tests258for(int i = 0; i < specialValues.length; i++) {259failures += testGetExponentCase(specialValues[i], specialResults[i]);260}261262263// Normal exponent tests264for(int i = Double.MIN_EXPONENT; i <= Double.MAX_EXPONENT; i++) {265int result;266267// Create power of two268double po2 = powerOfTwoD(i);269270failures += testGetExponentCase(po2, i);271272// Generate some random bit patterns for the significand273for(int j = 0; j < 10; j++) {274long randSignif = rand.nextLong();275double randFloat;276277randFloat = Double.longBitsToDouble( // Exponent278(Double.doubleToLongBits(po2)&279(~DoubleConsts.SIGNIF_BIT_MASK)) |280// Significand281(randSignif &282DoubleConsts.SIGNIF_BIT_MASK) );283284failures += testGetExponentCase(randFloat, i);285}286287if (i > Double.MIN_EXPONENT) {288double po2minus = Math.nextAfter(po2,289Double.NEGATIVE_INFINITY);290failures += testGetExponentCase(po2minus, i-1);291}292}293294// Subnormal exponent tests295296/*297* Start with MIN_VALUE, left shift, test high value, low298* values, and random in between.299*300* Use nextAfter to calculate, high value of previous binade;301* loop count i will indicate how many random bits, if any are302* needed.303*/304305double top=Double.MIN_VALUE;306for( int i = 1;307i < DoubleConsts.SIGNIFICAND_WIDTH;308i++, top *= 2.0f) {309310failures += testGetExponentCase(top,311Double.MIN_EXPONENT - 1);312313// Test largest value in next smaller binade314if (i >= 3) {// (i == 1) would test 0.0;315// (i == 2) would just retest MIN_VALUE316testGetExponentCase(Math.nextAfter(top, 0.0),317Double.MIN_EXPONENT - 1);318319if( i >= 10) {320// create a bit mask with (i-1) 1's in the low order321// bits322long mask = ~((~0L)<<(i-1));323double randFloat = Double.longBitsToDouble( // Exponent324Double.doubleToLongBits(top) |325// Significand326(rand.nextLong() & mask ) ) ;327328failures += testGetExponentCase(randFloat,329Double.MIN_EXPONENT - 1);330}331}332}333334return failures;335}336337338/* ******************** nextAfter tests ****************************** */339340static int testNextAfterCase(float start, double direction, float expected) {341int failures=0;342float minus_start = -start;343double minus_direction = -direction;344float minus_expected = -expected;345346failures+=Tests.test("Math.nextAfter(float,double)", start, direction,347Math.nextAfter(start, direction), expected);348failures+=Tests.test("Math.nextAfter(float,double)", minus_start, minus_direction,349Math.nextAfter(minus_start, minus_direction), minus_expected);350351failures+=Tests.test("StrictMath.nextAfter(float,double)", start, direction,352StrictMath.nextAfter(start, direction), expected);353failures+=Tests.test("StrictMath.nextAfter(float,double)", minus_start, minus_direction,354StrictMath.nextAfter(minus_start, minus_direction), minus_expected);355return failures;356}357358static int testNextAfterCase(double start, double direction, double expected) {359int failures=0;360361double minus_start = -start;362double minus_direction = -direction;363double minus_expected = -expected;364365failures+=Tests.test("Math.nextAfter(double,double)", start, direction,366Math.nextAfter(start, direction), expected);367failures+=Tests.test("Math.nextAfter(double,double)", minus_start, minus_direction,368Math.nextAfter(minus_start, minus_direction), minus_expected);369370failures+=Tests.test("StrictMath.nextAfter(double,double)", start, direction,371StrictMath.nextAfter(start, direction), expected);372failures+=Tests.test("StrictMath.nextAfter(double,double)", minus_start, minus_direction,373StrictMath.nextAfter(minus_start, minus_direction), minus_expected);374return failures;375}376377public static int testFloatNextAfter() {378int failures=0;379380/*381* Each row of the testCases matrix represents one test case382* for nexAfter; given the input of the first two columns, the383* result in the last column is expected.384*/385float [][] testCases = {386{NaNf, NaNf, NaNf},387{NaNf, 0.0f, NaNf},388{0.0f, NaNf, NaNf},389{NaNf, infinityF, NaNf},390{infinityF, NaNf, NaNf},391392{infinityF, infinityF, infinityF},393{infinityF, -infinityF, Float.MAX_VALUE},394{infinityF, 0.0f, Float.MAX_VALUE},395396{Float.MAX_VALUE, infinityF, infinityF},397{Float.MAX_VALUE, -infinityF, Float_MAX_VALUEmm},398{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE},399{Float.MAX_VALUE, 0.0f, Float_MAX_VALUEmm},400401{Float_MAX_VALUEmm, Float.MAX_VALUE, Float.MAX_VALUE},402{Float_MAX_VALUEmm, infinityF, Float.MAX_VALUE},403{Float_MAX_VALUEmm, Float_MAX_VALUEmm, Float_MAX_VALUEmm},404405{Float.MIN_NORMAL, infinityF, Float.MIN_NORMAL+406Float.MIN_VALUE},407{Float.MIN_NORMAL, -infinityF, Float_MAX_SUBNORMAL},408{Float.MIN_NORMAL, 1.0f, Float.MIN_NORMAL+409Float.MIN_VALUE},410{Float.MIN_NORMAL, -1.0f, Float_MAX_SUBNORMAL},411{Float.MIN_NORMAL, Float.MIN_NORMAL, Float.MIN_NORMAL},412413{Float_MAX_SUBNORMAL, Float.MIN_NORMAL, Float.MIN_NORMAL},414{Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL},415{Float_MAX_SUBNORMAL, 0.0f, Float_MAX_SUBNORMALmm},416417{Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL},418{Float_MAX_SUBNORMALmm, 0.0f, Float_MAX_SUBNORMALmm-Float.MIN_VALUE},419{Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMALmm},420421{Float.MIN_VALUE, 0.0f, 0.0f},422{-Float.MIN_VALUE, 0.0f, -0.0f},423{Float.MIN_VALUE, Float.MIN_VALUE, Float.MIN_VALUE},424{Float.MIN_VALUE, 1.0f, 2*Float.MIN_VALUE},425426// Make sure zero behavior is tested427{0.0f, 0.0f, 0.0f},428{0.0f, -0.0f, -0.0f},429{-0.0f, 0.0f, 0.0f},430{-0.0f, -0.0f, -0.0f},431{0.0f, infinityF, Float.MIN_VALUE},432{0.0f, -infinityF, -Float.MIN_VALUE},433{-0.0f, infinityF, Float.MIN_VALUE},434{-0.0f, -infinityF, -Float.MIN_VALUE},435{0.0f, Float.MIN_VALUE, Float.MIN_VALUE},436{0.0f, -Float.MIN_VALUE, -Float.MIN_VALUE},437{-0.0f, Float.MIN_VALUE, Float.MIN_VALUE},438{-0.0f, -Float.MIN_VALUE, -Float.MIN_VALUE}439};440441for(int i = 0; i < testCases.length; i++) {442failures += testNextAfterCase(testCases[i][0], testCases[i][1],443testCases[i][2]);444}445446return failures;447}448449public static int testDoubleNextAfter() {450int failures =0;451452/*453* Each row of the testCases matrix represents one test case454* for nexAfter; given the input of the first two columns, the455* result in the last column is expected.456*/457double [][] testCases = {458{NaNd, NaNd, NaNd},459{NaNd, 0.0d, NaNd},460{0.0d, NaNd, NaNd},461{NaNd, infinityD, NaNd},462{infinityD, NaNd, NaNd},463464{infinityD, infinityD, infinityD},465{infinityD, -infinityD, Double.MAX_VALUE},466{infinityD, 0.0d, Double.MAX_VALUE},467468{Double.MAX_VALUE, infinityD, infinityD},469{Double.MAX_VALUE, -infinityD, Double_MAX_VALUEmm},470{Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE},471{Double.MAX_VALUE, 0.0d, Double_MAX_VALUEmm},472473{Double_MAX_VALUEmm, Double.MAX_VALUE, Double.MAX_VALUE},474{Double_MAX_VALUEmm, infinityD, Double.MAX_VALUE},475{Double_MAX_VALUEmm, Double_MAX_VALUEmm, Double_MAX_VALUEmm},476477{Double.MIN_NORMAL, infinityD, Double.MIN_NORMAL+478Double.MIN_VALUE},479{Double.MIN_NORMAL, -infinityD, Double_MAX_SUBNORMAL},480{Double.MIN_NORMAL, 1.0f, Double.MIN_NORMAL+481Double.MIN_VALUE},482{Double.MIN_NORMAL, -1.0f, Double_MAX_SUBNORMAL},483{Double.MIN_NORMAL, Double.MIN_NORMAL, Double.MIN_NORMAL},484485{Double_MAX_SUBNORMAL, Double.MIN_NORMAL, Double.MIN_NORMAL},486{Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL},487{Double_MAX_SUBNORMAL, 0.0d, Double_MAX_SUBNORMALmm},488489{Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL},490{Double_MAX_SUBNORMALmm, 0.0d, Double_MAX_SUBNORMALmm-Double.MIN_VALUE},491{Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm},492493{Double.MIN_VALUE, 0.0d, 0.0d},494{-Double.MIN_VALUE, 0.0d, -0.0d},495{Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE},496{Double.MIN_VALUE, 1.0f, 2*Double.MIN_VALUE},497498// Make sure zero behavior is tested499{0.0d, 0.0d, 0.0d},500{0.0d, -0.0d, -0.0d},501{-0.0d, 0.0d, 0.0d},502{-0.0d, -0.0d, -0.0d},503{0.0d, infinityD, Double.MIN_VALUE},504{0.0d, -infinityD, -Double.MIN_VALUE},505{-0.0d, infinityD, Double.MIN_VALUE},506{-0.0d, -infinityD, -Double.MIN_VALUE},507{0.0d, Double.MIN_VALUE, Double.MIN_VALUE},508{0.0d, -Double.MIN_VALUE, -Double.MIN_VALUE},509{-0.0d, Double.MIN_VALUE, Double.MIN_VALUE},510{-0.0d, -Double.MIN_VALUE, -Double.MIN_VALUE}511};512513for(int i = 0; i < testCases.length; i++) {514failures += testNextAfterCase(testCases[i][0], testCases[i][1],515testCases[i][2]);516}517return failures;518}519520/* ******************** nextUp tests ********************************* */521522public static int testFloatNextUp() {523int failures=0;524525/*526* Each row of testCases represents one test case for nextUp;527* the first column is the input and the second column is the528* expected result.529*/530float testCases [][] = {531{NaNf, NaNf},532{-infinityF, -Float.MAX_VALUE},533{-Float.MAX_VALUE, -Float_MAX_VALUEmm},534{-Float.MIN_NORMAL, -Float_MAX_SUBNORMAL},535{-Float_MAX_SUBNORMAL, -Float_MAX_SUBNORMALmm},536{-Float.MIN_VALUE, -0.0f},537{-0.0f, Float.MIN_VALUE},538{+0.0f, Float.MIN_VALUE},539{Float.MIN_VALUE, Float.MIN_VALUE*2},540{Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMAL},541{Float_MAX_SUBNORMAL, Float.MIN_NORMAL},542{Float.MIN_NORMAL, Float.MIN_NORMAL+Float.MIN_VALUE},543{Float_MAX_VALUEmm, Float.MAX_VALUE},544{Float.MAX_VALUE, infinityF},545{infinityF, infinityF}546};547548for(int i = 0; i < testCases.length; i++) {549failures+=Tests.test("Math.nextUp(float)",550testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);551552failures+=Tests.test("StrictMath.nextUp(float)",553testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);554}555556return failures;557}558559560public static int testDoubleNextUp() {561int failures=0;562563/*564* Each row of testCases represents one test case for nextUp;565* the first column is the input and the second column is the566* expected result.567*/568double testCases [][] = {569{NaNd, NaNd},570{-infinityD, -Double.MAX_VALUE},571{-Double.MAX_VALUE, -Double_MAX_VALUEmm},572{-Double.MIN_NORMAL, -Double_MAX_SUBNORMAL},573{-Double_MAX_SUBNORMAL, -Double_MAX_SUBNORMALmm},574{-Double.MIN_VALUE, -0.0d},575{-0.0d, Double.MIN_VALUE},576{+0.0d, Double.MIN_VALUE},577{Double.MIN_VALUE, Double.MIN_VALUE*2},578{Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMAL},579{Double_MAX_SUBNORMAL, Double.MIN_NORMAL},580{Double.MIN_NORMAL, Double.MIN_NORMAL+Double.MIN_VALUE},581{Double_MAX_VALUEmm, Double.MAX_VALUE},582{Double.MAX_VALUE, infinityD},583{infinityD, infinityD}584};585586for(int i = 0; i < testCases.length; i++) {587failures+=Tests.test("Math.nextUp(double)",588testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);589590failures+=Tests.test("StrictMath.nextUp(double)",591testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);592}593594return failures;595}596597/* ******************** nextDown tests ********************************* */598599public static int testFloatNextDown() {600int failures=0;601602/*603* Each row of testCases represents one test case for nextDown;604* the first column is the input and the second column is the605* expected result.606*/607float testCases [][] = {608{NaNf, NaNf},609{-infinityF, -infinityF},610{-Float.MAX_VALUE, -infinityF},611{-Float_MAX_VALUEmm, -Float.MAX_VALUE},612{-Float_MAX_SUBNORMAL, -Float.MIN_NORMAL},613{-Float_MAX_SUBNORMALmm, -Float_MAX_SUBNORMAL},614{-0.0f, -Float.MIN_VALUE},615{+0.0f, -Float.MIN_VALUE},616{Float.MIN_VALUE, 0.0f},617{Float.MIN_VALUE*2, Float.MIN_VALUE},618{Float_MAX_SUBNORMAL, Float_MAX_SUBNORMALmm},619{Float.MIN_NORMAL, Float_MAX_SUBNORMAL},620{Float.MIN_NORMAL+621Float.MIN_VALUE, Float.MIN_NORMAL},622{Float.MAX_VALUE, Float_MAX_VALUEmm},623{infinityF, Float.MAX_VALUE},624};625626for(int i = 0; i < testCases.length; i++) {627failures+=Tests.test("Math.nextDown(float)",628testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]);629630failures+=Tests.test("StrictMath.nextDown(float)",631testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]);632}633634return failures;635}636637638public static int testDoubleNextDown() {639int failures=0;640641/*642* Each row of testCases represents one test case for nextDown;643* the first column is the input and the second column is the644* expected result.645*/646double testCases [][] = {647{NaNd, NaNd},648{-infinityD, -infinityD},649{-Double.MAX_VALUE, -infinityD},650{-Double_MAX_VALUEmm, -Double.MAX_VALUE},651{-Double_MAX_SUBNORMAL, -Double.MIN_NORMAL},652{-Double_MAX_SUBNORMALmm, -Double_MAX_SUBNORMAL},653{-0.0d, -Double.MIN_VALUE},654{+0.0d, -Double.MIN_VALUE},655{Double.MIN_VALUE, 0.0d},656{Double.MIN_VALUE*2, Double.MIN_VALUE},657{Double_MAX_SUBNORMAL, Double_MAX_SUBNORMALmm},658{Double.MIN_NORMAL, Double_MAX_SUBNORMAL},659{Double.MIN_NORMAL+660Double.MIN_VALUE, Double.MIN_NORMAL},661{Double.MAX_VALUE, Double_MAX_VALUEmm},662{infinityD, Double.MAX_VALUE},663};664665for(int i = 0; i < testCases.length; i++) {666failures+=Tests.test("Math.nextDown(double)",667testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]);668669failures+=Tests.test("StrictMath.nextDown(double)",670testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]);671}672673return failures;674}675676677/* ********************** boolean tests ****************************** */678679/*680* Combined tests for boolean functions, isFinite, isInfinite,681* isNaN, isUnordered.682*/683684public static int testFloatBooleanMethods() {685int failures = 0;686687float testCases [] = {688NaNf,689-infinityF,690infinityF,691-Float.MAX_VALUE,692-3.0f,693-1.0f,694-Float.MIN_NORMAL,695-Float_MAX_SUBNORMALmm,696-Float_MAX_SUBNORMAL,697-Float.MIN_VALUE,698-0.0f,699+0.0f,700Float.MIN_VALUE,701Float_MAX_SUBNORMALmm,702Float_MAX_SUBNORMAL,703Float.MIN_NORMAL,7041.0f,7053.0f,706Float_MAX_VALUEmm,707Float.MAX_VALUE708};709710for(int i = 0; i < testCases.length; i++) {711// isNaN712failures+=Tests.test("Float.isNaN(float)", testCases[i],713Float.isNaN(testCases[i]), (i ==0));714715// isFinite716failures+=Tests.test("Float.isFinite(float)", testCases[i],717Float.isFinite(testCases[i]), (i >= 3));718719// isInfinite720failures+=Tests.test("Float.isInfinite(float)", testCases[i],721Float.isInfinite(testCases[i]), (i==1 || i==2));722723// isUnorderd724for(int j = 0; j < testCases.length; j++) {725failures+=Tests.test("Tests.isUnordered(float, float)", testCases[i],testCases[j],726Tests.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));727}728}729730return failures;731}732733public static int testDoubleBooleanMethods() {734int failures = 0;735boolean result = false;736737double testCases [] = {738NaNd,739-infinityD,740infinityD,741-Double.MAX_VALUE,742-3.0d,743-1.0d,744-Double.MIN_NORMAL,745-Double_MAX_SUBNORMALmm,746-Double_MAX_SUBNORMAL,747-Double.MIN_VALUE,748-0.0d,749+0.0d,750Double.MIN_VALUE,751Double_MAX_SUBNORMALmm,752Double_MAX_SUBNORMAL,753Double.MIN_NORMAL,7541.0d,7553.0d,756Double_MAX_VALUEmm,757Double.MAX_VALUE758};759760for(int i = 0; i < testCases.length; i++) {761// isNaN762failures+=Tests.test("Double.isNaN(double)", testCases[i],763Double.isNaN(testCases[i]), (i ==0));764765// isFinite766failures+=Tests.test("Double.isFinite(double)", testCases[i],767Double.isFinite(testCases[i]), (i >= 3));768769// isInfinite770failures+=Tests.test("Double.isInfinite(double)", testCases[i],771Double.isInfinite(testCases[i]), (i==1 || i==2));772773// isUnorderd774for(int j = 0; j < testCases.length; j++) {775failures+=Tests.test("Tests.isUnordered(double, double)", testCases[i],testCases[j],776Tests.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));777}778}779780return failures;781}782783/* ******************** copySign tests******************************** */784785public static int testFloatCopySign() {786int failures = 0;787788// testCases[0] are logically positive numbers;789// testCases[1] are negative numbers.790float testCases [][] = {791{+0.0f,792Float.MIN_VALUE,793Float_MAX_SUBNORMALmm,794Float_MAX_SUBNORMAL,795Float.MIN_NORMAL,7961.0f,7973.0f,798Float_MAX_VALUEmm,799Float.MAX_VALUE,800infinityF,801},802{-infinityF,803-Float.MAX_VALUE,804-3.0f,805-1.0f,806-Float.MIN_NORMAL,807-Float_MAX_SUBNORMALmm,808-Float_MAX_SUBNORMAL,809-Float.MIN_VALUE,810-0.0f}811};812813float NaNs[] = {Float.intBitsToFloat(0x7fc00000), // "positive" NaN814Float.intBitsToFloat(0xFfc00000)}; // "negative" NaN815816// Tests shared between raw and non-raw versions817for(int i = 0; i < 2; i++) {818for(int j = 0; j < 2; j++) {819for(int m = 0; m < testCases[i].length; m++) {820for(int n = 0; n < testCases[j].length; n++) {821// copySign(magnitude, sign)822failures+=Tests.test("Math.copySign(float,float)",823testCases[i][m],testCases[j][n],824Math.copySign(testCases[i][m], testCases[j][n]),825(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );826827failures+=Tests.test("StrictMath.copySign(float,float)",828testCases[i][m],testCases[j][n],829StrictMath.copySign(testCases[i][m], testCases[j][n]),830(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );831}832}833}834}835836// For rawCopySign, NaN may effectively have either sign bit837// while for copySign NaNs are treated as if they always have838// a zero sign bit (i.e. as positive numbers)839for(int i = 0; i < 2; i++) {840for(int j = 0; j < NaNs.length; j++) {841for(int m = 0; m < testCases[i].length; m++) {842// copySign(magnitude, sign)843844failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==845Math.abs(testCases[i][m])) ? 0:1;846847848failures+=Tests.test("StrictMath.copySign(float,float)",849testCases[i][m], NaNs[j],850StrictMath.copySign(testCases[i][m], NaNs[j]),851Math.abs(testCases[i][m]) );852}853}854}855856return failures;857}858859public static int testDoubleCopySign() {860int failures = 0;861862// testCases[0] are logically positive numbers;863// testCases[1] are negative numbers.864double testCases [][] = {865{+0.0d,866Double.MIN_VALUE,867Double_MAX_SUBNORMALmm,868Double_MAX_SUBNORMAL,869Double.MIN_NORMAL,8701.0d,8713.0d,872Double_MAX_VALUEmm,873Double.MAX_VALUE,874infinityD,875},876{-infinityD,877-Double.MAX_VALUE,878-3.0d,879-1.0d,880-Double.MIN_NORMAL,881-Double_MAX_SUBNORMALmm,882-Double_MAX_SUBNORMAL,883-Double.MIN_VALUE,884-0.0d}885};886887double NaNs[] = {Double.longBitsToDouble(0x7ff8000000000000L), // "positive" NaN888Double.longBitsToDouble(0xfff8000000000000L), // "negative" NaN889Double.longBitsToDouble(0x7FF0000000000001L),890Double.longBitsToDouble(0xFFF0000000000001L),891Double.longBitsToDouble(0x7FF8555555555555L),892Double.longBitsToDouble(0xFFF8555555555555L),893Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),894Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),895Double.longBitsToDouble(0x7FFDeadBeef00000L),896Double.longBitsToDouble(0xFFFDeadBeef00000L),897Double.longBitsToDouble(0x7FFCafeBabe00000L),898Double.longBitsToDouble(0xFFFCafeBabe00000L)};899900// Tests shared between Math and StrictMath versions901for(int i = 0; i < 2; i++) {902for(int j = 0; j < 2; j++) {903for(int m = 0; m < testCases[i].length; m++) {904for(int n = 0; n < testCases[j].length; n++) {905// copySign(magnitude, sign)906failures+=Tests.test("MathcopySign(double,double)",907testCases[i][m],testCases[j][n],908Math.copySign(testCases[i][m], testCases[j][n]),909(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );910911failures+=Tests.test("StrictMath.copySign(double,double)",912testCases[i][m],testCases[j][n],913StrictMath.copySign(testCases[i][m], testCases[j][n]),914(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );915}916}917}918}919920// For Math.copySign, NaN may effectively have either sign bit921// while for StrictMath.copySign NaNs are treated as if they922// always have a zero sign bit (i.e. as positive numbers)923for(int i = 0; i < 2; i++) {924for(int j = 0; j < NaNs.length; j++) {925for(int m = 0; m < testCases[i].length; m++) {926// copySign(magnitude, sign)927928failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==929Math.abs(testCases[i][m])) ? 0:1;930931932failures+=Tests.test("StrictMath.copySign(double,double)",933testCases[i][m], NaNs[j],934StrictMath.copySign(testCases[i][m], NaNs[j]),935Math.abs(testCases[i][m]) );936}937}938}939940941return failures;942}943944/* ************************ scalb tests ******************************* */945946static int testScalbCase(float value, int scale_factor, float expected) {947int failures=0;948949failures+=Tests.test("Math.scalb(float,int)",950value, scale_factor,951Math.scalb(value, scale_factor), expected);952953failures+=Tests.test("Math.scalb(float,int)",954-value, scale_factor,955Math.scalb(-value, scale_factor), -expected);956957failures+=Tests.test("StrictMath.scalb(float,int)",958value, scale_factor,959StrictMath.scalb(value, scale_factor), expected);960961failures+=Tests.test("StrictMath.scalb(float,int)",962-value, scale_factor,963StrictMath.scalb(-value, scale_factor), -expected);964return failures;965}966967public static int testFloatScalb() {968int failures=0;969int MAX_SCALE = Float.MAX_EXPONENT + -Float.MIN_EXPONENT +970FloatConsts.SIGNIFICAND_WIDTH + 1;971972973// Arguments x, where scalb(x,n) is x for any n.974float [] identityTestCases = {NaNf,975-0.0f,976+0.0f,977infinityF,978-infinityF979};980981float [] subnormalTestCases = {982Float.MIN_VALUE,9833.0f*Float.MIN_VALUE,984Float_MAX_SUBNORMALmm,985Float_MAX_SUBNORMAL986};987988float [] someTestCases = {989Float.MIN_VALUE,9903.0f*Float.MIN_VALUE,991Float_MAX_SUBNORMALmm,992Float_MAX_SUBNORMAL,993Float.MIN_NORMAL,9941.0f,9952.0f,9963.0f,997(float)Math.PI,998Float_MAX_VALUEmm,999Float.MAX_VALUE1000};10011002int [] oneMultiplyScalingFactors = {1003Float.MIN_EXPONENT,1004Float.MIN_EXPONENT+1,1005-3,1006-2,1007-1,10080,10091,10102,10113,1012Float.MAX_EXPONENT-1,1013Float.MAX_EXPONENT1014};10151016int [] manyScalingFactors = {1017Integer.MIN_VALUE,1018Integer.MIN_VALUE+1,1019-MAX_SCALE -1,1020-MAX_SCALE,1021-MAX_SCALE+1,102210232*Float.MIN_EXPONENT-1, // -25310242*Float.MIN_EXPONENT, // -25210252*Float.MIN_EXPONENT+1, // -25110261027Float.MIN_EXPONENT - FloatConsts.SIGNIFICAND_WIDTH,1028FloatConsts.MIN_SUB_EXPONENT,1029-Float.MAX_EXPONENT, // -1271030Float.MIN_EXPONENT, // -12610311032-2,1033-1,10340,10351,10362,10371038Float.MAX_EXPONENT-1, // 1261039Float.MAX_EXPONENT, // 1271040Float.MAX_EXPONENT+1, // 128104110422*Float.MAX_EXPONENT-1, // 25310432*Float.MAX_EXPONENT, // 25410442*Float.MAX_EXPONENT+1, // 25510451046MAX_SCALE-1,1047MAX_SCALE,1048MAX_SCALE+1,1049Integer.MAX_VALUE-1,1050Integer.MAX_VALUE1051};10521053// Test cases where scaling is always a no-op1054for(int i=0; i < identityTestCases.length; i++) {1055for(int j=0; j < manyScalingFactors.length; j++) {1056failures += testScalbCase(identityTestCases[i],1057manyScalingFactors[j],1058identityTestCases[i]);1059}1060}10611062// Test cases where result is 0.0 or infinity due to magnitude1063// of the scaling factor1064for(int i=0; i < someTestCases.length; i++) {1065for(int j=0; j < manyScalingFactors.length; j++) {1066int scaleFactor = manyScalingFactors[j];1067if (Math.abs(scaleFactor) >= MAX_SCALE) {1068float value = someTestCases[i];1069failures+=testScalbCase(value,1070scaleFactor,1071Math.copySign( (scaleFactor>0?infinityF:0.0f), value) );1072}1073}1074}10751076// Test cases that could be done with one floating-point1077// multiply.1078for(int i=0; i < someTestCases.length; i++) {1079for(int j=0; j < oneMultiplyScalingFactors.length; j++) {1080int scaleFactor = oneMultiplyScalingFactors[j];1081float value = someTestCases[i];10821083failures+=testScalbCase(value,1084scaleFactor,1085value*powerOfTwoF(scaleFactor));1086}1087}10881089// Create 2^MAX_EXPONENT1090float twoToTheMaxExp = 1.0f; // 2^01091for(int i = 0; i < Float.MAX_EXPONENT; i++)1092twoToTheMaxExp *=2.0f;10931094// Scale-up subnormal values until they all overflow1095for(int i=0; i < subnormalTestCases.length; i++) {1096float scale = 1.0f; // 2^j1097float value = subnormalTestCases[i];10981099for(int j=Float.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow1100int scaleFactor = j;11011102failures+=testScalbCase(value,1103scaleFactor,1104(Tests.ilogb(value) +j > Float.MAX_EXPONENT ) ?1105Math.copySign(infinityF, value) : // overflow1106// calculate right answer1107twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );1108scale*=2.0f;1109}1110}11111112// Scale down a large number until it underflows. By scaling1113// down MAX_NORMALmm, the first subnormal result will be exact1114// but the next one will round -- all those results can be1115// checked by halving a separate value in the loop. Actually,1116// we can keep halving and checking until the product is zero1117// since:1118//1119// 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact1120// it will round *up*1121//1122// 2. When rounding first occurs in the expected product, it1123// too rounds up, to 2^-MAX_EXPONENT.1124//1125// Halving expected after rounding happends to give the same1126// result as the scalb operation.1127float expected = Float_MAX_VALUEmm *0.5f;1128for(int i = -1; i > -MAX_SCALE; i--) {1129failures+=testScalbCase(Float_MAX_VALUEmm, i, expected);11301131expected *= 0.5f;1132}11331134// Tricky rounding tests:1135// Scale down a large number into subnormal range such that if1136// scalb is being implemented with multiple floating-point1137// multiplies, the value would round twice if the multiplies1138// were done in the wrong order.11391140float value = 0x8.0000bP-5f;1141expected = 0x1.00001p-129f;11421143for(int i = 0; i < 129; i++) {1144failures+=testScalbCase(value,1145-127-i,1146expected);1147value *=2.0f;1148}11491150return failures;1151}11521153static int testScalbCase(double value, int scale_factor, double expected) {1154int failures=0;11551156failures+=Tests.test("Math.scalb(double,int)",1157value, scale_factor,1158Math.scalb(value, scale_factor), expected);11591160failures+=Tests.test("Math.scalb(double,int)",1161-value, scale_factor,1162Math.scalb(-value, scale_factor), -expected);11631164failures+=Tests.test("StrictMath.scalb(double,int)",1165value, scale_factor,1166StrictMath.scalb(value, scale_factor), expected);11671168failures+=Tests.test("StrictMath.scalb(double,int)",1169-value, scale_factor,1170StrictMath.scalb(-value, scale_factor), -expected);11711172return failures;1173}11741175public static int testDoubleScalb() {1176int failures=0;1177int MAX_SCALE = Double.MAX_EXPONENT + -Double.MIN_EXPONENT +1178DoubleConsts.SIGNIFICAND_WIDTH + 1;117911801181// Arguments x, where scalb(x,n) is x for any n.1182double [] identityTestCases = {NaNd,1183-0.0,1184+0.0,1185infinityD,1186};11871188double [] subnormalTestCases = {1189Double.MIN_VALUE,11903.0d*Double.MIN_VALUE,1191Double_MAX_SUBNORMALmm,1192Double_MAX_SUBNORMAL1193};11941195double [] someTestCases = {1196Double.MIN_VALUE,11973.0d*Double.MIN_VALUE,1198Double_MAX_SUBNORMALmm,1199Double_MAX_SUBNORMAL,1200Double.MIN_NORMAL,12011.0d,12022.0d,12033.0d,1204Math.PI,1205Double_MAX_VALUEmm,1206Double.MAX_VALUE1207};12081209int [] oneMultiplyScalingFactors = {1210Double.MIN_EXPONENT,1211Double.MIN_EXPONENT+1,1212-3,1213-2,1214-1,12150,12161,12172,12183,1219Double.MAX_EXPONENT-1,1220Double.MAX_EXPONENT1221};12221223int [] manyScalingFactors = {1224Integer.MIN_VALUE,1225Integer.MIN_VALUE+1,1226-MAX_SCALE -1,1227-MAX_SCALE,1228-MAX_SCALE+1,122912302*Double.MIN_EXPONENT-1, // -204512312*Double.MIN_EXPONENT, // -204412322*Double.MIN_EXPONENT+1, // -204312331234Double.MIN_EXPONENT, // -10221235Double.MIN_EXPONENT - DoubleConsts.SIGNIFICAND_WIDTH,1236DoubleConsts.MIN_SUB_EXPONENT,1237-Double.MAX_EXPONENT, // -10231238Double.MIN_EXPONENT, // -102212391240-2,1241-1,12420,12431,12442,12451246Double.MAX_EXPONENT-1, // 10221247Double.MAX_EXPONENT, // 10231248Double.MAX_EXPONENT+1, // 1024124912502*Double.MAX_EXPONENT-1, // 204512512*Double.MAX_EXPONENT, // 204612522*Double.MAX_EXPONENT+1, // 204712531254MAX_SCALE-1,1255MAX_SCALE,1256MAX_SCALE+1,1257Integer.MAX_VALUE-1,1258Integer.MAX_VALUE1259};12601261// Test cases where scaling is always a no-op1262for(int i=0; i < identityTestCases.length; i++) {1263for(int j=0; j < manyScalingFactors.length; j++) {1264failures += testScalbCase(identityTestCases[i],1265manyScalingFactors[j],1266identityTestCases[i]);1267}1268}12691270// Test cases where result is 0.0 or infinity due to magnitude1271// of the scaling factor1272for(int i=0; i < someTestCases.length; i++) {1273for(int j=0; j < manyScalingFactors.length; j++) {1274int scaleFactor = manyScalingFactors[j];1275if (Math.abs(scaleFactor) >= MAX_SCALE) {1276double value = someTestCases[i];1277failures+=testScalbCase(value,1278scaleFactor,1279Math.copySign( (scaleFactor>0?infinityD:0.0), value) );1280}1281}1282}12831284// Test cases that could be done with one floating-point1285// multiply.1286for(int i=0; i < someTestCases.length; i++) {1287for(int j=0; j < oneMultiplyScalingFactors.length; j++) {1288int scaleFactor = oneMultiplyScalingFactors[j];1289double value = someTestCases[i];12901291failures+=testScalbCase(value,1292scaleFactor,1293value*powerOfTwoD(scaleFactor));1294}1295}12961297// Create 2^MAX_EXPONENT1298double twoToTheMaxExp = 1.0; // 2^01299for(int i = 0; i < Double.MAX_EXPONENT; i++)1300twoToTheMaxExp *=2.0;13011302// Scale-up subnormal values until they all overflow1303for(int i=0; i < subnormalTestCases.length; i++) {1304double scale = 1.0; // 2^j1305double value = subnormalTestCases[i];13061307for(int j=Double.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow1308int scaleFactor = j;13091310failures+=testScalbCase(value,1311scaleFactor,1312(Tests.ilogb(value) +j > Double.MAX_EXPONENT ) ?1313Math.copySign(infinityD, value) : // overflow1314// calculate right answer1315twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );1316scale*=2.0;1317}1318}13191320// Scale down a large number until it underflows. By scaling1321// down MAX_NORMALmm, the first subnormal result will be exact1322// but the next one will round -- all those results can be1323// checked by halving a separate value in the loop. Actually,1324// we can keep halving and checking until the product is zero1325// since:1326//1327// 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact1328// it will round *up*1329//1330// 2. When rounding first occurs in the expected product, it1331// too rounds up, to 2^-MAX_EXPONENT.1332//1333// Halving expected after rounding happends to give the same1334// result as the scalb operation.1335double expected = Double_MAX_VALUEmm *0.5f;1336for(int i = -1; i > -MAX_SCALE; i--) {1337failures+=testScalbCase(Double_MAX_VALUEmm, i, expected);13381339expected *= 0.5;1340}13411342// Tricky rounding tests:1343// Scale down a large number into subnormal range such that if1344// scalb is being implemented with multiple floating-point1345// multiplies, the value would round twice if the multiplies1346// were done in the wrong order.13471348double value = 0x1.000000000000bP-1;1349expected = 0x0.2000000000001P-1022;1350for(int i = 0; i < Double.MAX_EXPONENT+2; i++) {1351failures+=testScalbCase(value,1352-1024-i,1353expected);1354value *=2.0;1355}13561357return failures;1358}13591360/* ************************* ulp tests ******************************* */136113621363/*1364* Test Math.ulp and StrictMath.ulp with +d and -d.1365*/1366static int testUlpCase(float f, float expected) {1367float minus_f = -f;1368int failures=0;13691370failures+=Tests.test("Math.ulp(float)", f,1371Math.ulp(f), expected);1372failures+=Tests.test("Math.ulp(float)", minus_f,1373Math.ulp(minus_f), expected);1374failures+=Tests.test("StrictMath.ulp(float)", f,1375StrictMath.ulp(f), expected);1376failures+=Tests.test("StrictMath.ulp(float)", minus_f,1377StrictMath.ulp(minus_f), expected);1378return failures;1379}13801381static int testUlpCase(double d, double expected) {1382double minus_d = -d;1383int failures=0;13841385failures+=Tests.test("Math.ulp(double)", d,1386Math.ulp(d), expected);1387failures+=Tests.test("Math.ulp(double)", minus_d,1388Math.ulp(minus_d), expected);1389failures+=Tests.test("StrictMath.ulp(double)", d,1390StrictMath.ulp(d), expected);1391failures+=Tests.test("StrictMath.ulp(double)", minus_d,1392StrictMath.ulp(minus_d), expected);1393return failures;1394}13951396public static int testFloatUlp() {1397int failures = 0;1398float [] specialValues = {NaNf,1399Float.POSITIVE_INFINITY,1400+0.0f,1401+1.0f,1402+2.0f,1403+16.0f,1404+Float.MIN_VALUE,1405+Float_MAX_SUBNORMAL,1406+Float.MIN_NORMAL,1407+Float.MAX_VALUE1408};14091410float [] specialResults = {NaNf,1411Float.POSITIVE_INFINITY,1412Float.MIN_VALUE,1413powerOfTwoF(-23),1414powerOfTwoF(-22),1415powerOfTwoF(-19),1416Float.MIN_VALUE,1417Float.MIN_VALUE,1418Float.MIN_VALUE,1419powerOfTwoF(104)1420};14211422// Special value tests1423for(int i = 0; i < specialValues.length; i++) {1424failures += testUlpCase(specialValues[i], specialResults[i]);1425}142614271428// Normal exponent tests1429for(int i = Float.MIN_EXPONENT; i <= Float.MAX_EXPONENT; i++) {1430float expected;14311432// Create power of two1433float po2 = powerOfTwoF(i);1434expected = Math.scalb(1.0f, i - (FloatConsts.SIGNIFICAND_WIDTH-1));14351436failures += testUlpCase(po2, expected);14371438// Generate some random bit patterns for the significand1439for(int j = 0; j < 10; j++) {1440int randSignif = rand.nextInt();1441float randFloat;14421443randFloat = Float.intBitsToFloat( // Exponent1444(Float.floatToIntBits(po2)&1445(~FloatConsts.SIGNIF_BIT_MASK)) |1446// Significand1447(randSignif &1448FloatConsts.SIGNIF_BIT_MASK) );14491450failures += testUlpCase(randFloat, expected);1451}14521453if (i > Float.MIN_EXPONENT) {1454float po2minus = Math.nextAfter(po2,1455Float.NEGATIVE_INFINITY);1456failures += testUlpCase(po2minus, expected/2.0f);1457}1458}14591460// Subnormal tests14611462/*1463* Start with MIN_VALUE, left shift, test high value, low1464* values, and random in between.1465*1466* Use nextAfter to calculate, high value of previous binade,1467* loop count i will indicate how many random bits, if any are1468* needed.1469*/14701471float top=Float.MIN_VALUE;1472for( int i = 1;1473i < FloatConsts.SIGNIFICAND_WIDTH;1474i++, top *= 2.0f) {14751476failures += testUlpCase(top, Float.MIN_VALUE);14771478// Test largest value in next smaller binade1479if (i >= 3) {// (i == 1) would test 0.0;1480// (i == 2) would just retest MIN_VALUE1481testUlpCase(Math.nextAfter(top, 0.0f),1482Float.MIN_VALUE);14831484if( i >= 10) {1485// create a bit mask with (i-1) 1's in the low order1486// bits1487int mask = ~((~0)<<(i-1));1488float randFloat = Float.intBitsToFloat( // Exponent1489Float.floatToIntBits(top) |1490// Significand1491(rand.nextInt() & mask ) ) ;14921493failures += testUlpCase(randFloat, Float.MIN_VALUE);1494}1495}1496}14971498return failures;1499}15001501public static int testDoubleUlp() {1502int failures = 0;1503double [] specialValues = {NaNd,1504Double.POSITIVE_INFINITY,1505+0.0d,1506+1.0d,1507+2.0d,1508+16.0d,1509+Double.MIN_VALUE,1510+Double_MAX_SUBNORMAL,1511+Double.MIN_NORMAL,1512+Double.MAX_VALUE1513};15141515double [] specialResults = {NaNf,1516Double.POSITIVE_INFINITY,1517Double.MIN_VALUE,1518powerOfTwoD(-52),1519powerOfTwoD(-51),1520powerOfTwoD(-48),1521Double.MIN_VALUE,1522Double.MIN_VALUE,1523Double.MIN_VALUE,1524powerOfTwoD(971)1525};15261527// Special value tests1528for(int i = 0; i < specialValues.length; i++) {1529failures += testUlpCase(specialValues[i], specialResults[i]);1530}153115321533// Normal exponent tests1534for(int i = Double.MIN_EXPONENT; i <= Double.MAX_EXPONENT; i++) {1535double expected;15361537// Create power of two1538double po2 = powerOfTwoD(i);1539expected = Math.scalb(1.0, i - (DoubleConsts.SIGNIFICAND_WIDTH-1));15401541failures += testUlpCase(po2, expected);15421543// Generate some random bit patterns for the significand1544for(int j = 0; j < 10; j++) {1545long randSignif = rand.nextLong();1546double randDouble;15471548randDouble = Double.longBitsToDouble( // Exponent1549(Double.doubleToLongBits(po2)&1550(~DoubleConsts.SIGNIF_BIT_MASK)) |1551// Significand1552(randSignif &1553DoubleConsts.SIGNIF_BIT_MASK) );15541555failures += testUlpCase(randDouble, expected);1556}15571558if (i > Double.MIN_EXPONENT) {1559double po2minus = Math.nextAfter(po2,1560Double.NEGATIVE_INFINITY);1561failures += testUlpCase(po2minus, expected/2.0f);1562}1563}15641565// Subnormal tests15661567/*1568* Start with MIN_VALUE, left shift, test high value, low1569* values, and random in between.1570*1571* Use nextAfter to calculate, high value of previous binade,1572* loop count i will indicate how many random bits, if any are1573* needed.1574*/15751576double top=Double.MIN_VALUE;1577for( int i = 1;1578i < DoubleConsts.SIGNIFICAND_WIDTH;1579i++, top *= 2.0f) {15801581failures += testUlpCase(top, Double.MIN_VALUE);15821583// Test largest value in next smaller binade1584if (i >= 3) {// (i == 1) would test 0.0;1585// (i == 2) would just retest MIN_VALUE1586testUlpCase(Math.nextAfter(top, 0.0f),1587Double.MIN_VALUE);15881589if( i >= 10) {1590// create a bit mask with (i-1) 1's in the low order1591// bits1592int mask = ~((~0)<<(i-1));1593double randDouble = Double.longBitsToDouble( // Exponent1594Double.doubleToLongBits(top) |1595// Significand1596(rand.nextLong() & mask ) ) ;15971598failures += testUlpCase(randDouble, Double.MIN_VALUE);1599}1600}1601}16021603return failures;1604}16051606public static int testFloatSignum() {1607int failures = 0;1608float testCases [][] = {1609{NaNf, NaNf},1610{-infinityF, -1.0f},1611{-Float.MAX_VALUE, -1.0f},1612{-Float.MIN_NORMAL, -1.0f},1613{-1.0f, -1.0f},1614{-2.0f, -1.0f},1615{-Float_MAX_SUBNORMAL, -1.0f},1616{-Float.MIN_VALUE, -1.0f},1617{-0.0f, -0.0f},1618{+0.0f, +0.0f},1619{Float.MIN_VALUE, 1.0f},1620{Float_MAX_SUBNORMALmm, 1.0f},1621{Float_MAX_SUBNORMAL, 1.0f},1622{Float.MIN_NORMAL, 1.0f},1623{1.0f, 1.0f},1624{2.0f, 1.0f},1625{Float_MAX_VALUEmm, 1.0f},1626{Float.MAX_VALUE, 1.0f},1627{infinityF, 1.0f}1628};16291630for(int i = 0; i < testCases.length; i++) {1631failures+=Tests.test("Math.signum(float)",1632testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);1633failures+=Tests.test("StrictMath.signum(float)",1634testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);1635}16361637return failures;1638}16391640public static int testDoubleSignum() {1641int failures = 0;1642double testCases [][] = {1643{NaNd, NaNd},1644{-infinityD, -1.0},1645{-Double.MAX_VALUE, -1.0},1646{-Double.MIN_NORMAL, -1.0},1647{-1.0, -1.0},1648{-2.0, -1.0},1649{-Double_MAX_SUBNORMAL, -1.0},1650{-Double.MIN_VALUE, -1.0d},1651{-0.0d, -0.0d},1652{+0.0d, +0.0d},1653{Double.MIN_VALUE, 1.0},1654{Double_MAX_SUBNORMALmm, 1.0},1655{Double_MAX_SUBNORMAL, 1.0},1656{Double.MIN_NORMAL, 1.0},1657{1.0, 1.0},1658{2.0, 1.0},1659{Double_MAX_VALUEmm, 1.0},1660{Double.MAX_VALUE, 1.0},1661{infinityD, 1.0}1662};16631664for(int i = 0; i < testCases.length; i++) {1665failures+=Tests.test("Math.signum(double)",1666testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);1667failures+=Tests.test("StrictMath.signum(double)",1668testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);1669}16701671return failures;1672}167316741675public static void main(String argv[]) {1676int failures = 0;16771678failures += testFloatGetExponent();1679failures += testDoubleGetExponent();16801681failures += testFloatNextAfter();1682failures += testDoubleNextAfter();16831684failures += testFloatNextUp();1685failures += testDoubleNextUp();16861687failures += testFloatNextDown();1688failures += testDoubleNextDown();16891690failures += testFloatBooleanMethods();1691failures += testDoubleBooleanMethods();16921693failures += testFloatCopySign();1694failures += testDoubleCopySign();16951696failures += testFloatScalb();1697failures += testDoubleScalb();16981699failures += testFloatUlp();1700failures += testDoubleUlp();17011702failures += testFloatSignum();1703failures += testDoubleSignum();17041705if (failures > 0) {1706System.err.println("Testing the recommended functions incurred "1707+ failures + " failures.");1708throw new RuntimeException();1709}1710}1711}171217131714