Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/Math/IeeeRecommendedTests.java
38812 views
/*1* Copyright (c) 2003, 2011, 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* @bug 4860891 4826732 4780454 4939441 482665226* @summary Tests for IEEE 754[R] recommended functions and similar methods27* @author Joseph D. Darcy28* @key randomness29*/3031import sun.misc.FpUtils;32import sun.misc.DoubleConsts;33import sun.misc.FloatConsts;3435public class IeeeRecommendedTests {36private IeeeRecommendedTests(){}3738static final float NaNf = Float.NaN;39static final double NaNd = Double.NaN;40static final float infinityF = Float.POSITIVE_INFINITY;41static final double infinityD = Double.POSITIVE_INFINITY;4243static final float Float_MAX_VALUEmm = 0x1.fffffcP+127f;44static final float Float_MAX_SUBNORMAL = 0x0.fffffeP-126f;45static final float Float_MAX_SUBNORMALmm = 0x0.fffffcP-126f;4647static final double Double_MAX_VALUEmm = 0x1.ffffffffffffeP+1023;48static final double Double_MAX_SUBNORMAL = 0x0.fffffffffffffP-1022;49static final double Double_MAX_SUBNORMALmm = 0x0.ffffffffffffeP-1022;5051// Initialize shared random number generator52static java.util.Random rand = new java.util.Random();5354/**55* Returns a floating-point power of two in the normal range.56*/57static double powerOfTwoD(int n) {58return Double.longBitsToDouble((((long)n + (long)DoubleConsts.MAX_EXPONENT) <<59(DoubleConsts.SIGNIFICAND_WIDTH-1))60& DoubleConsts.EXP_BIT_MASK);61}6263/**64* Returns a floating-point power of two in the normal range.65*/66static float powerOfTwoF(int n) {67return Float.intBitsToFloat(((n + FloatConsts.MAX_EXPONENT) <<68(FloatConsts.SIGNIFICAND_WIDTH-1))69& FloatConsts.EXP_BIT_MASK);70}7172/* ******************** getExponent tests ****************************** */7374/*75* The tests for getExponent should test the special values (NaN, +/-76* infinity, etc.), test the endpoints of each binade (set of77* floating-point values with the same exponent), and for good78* measure, test some random values within each binade. Testing79* the endpoints of each binade includes testing both positive and80* negative numbers. Subnormal values with different normalized81* exponents should be tested too. Both Math and StrictMath82* methods should return the same results.83*/8485/*86* Test Math.getExponent and StrictMath.getExponent with +d and -d.87*/88static int testGetExponentCase(float f, int expected) {89float minus_f = -f;90int failures=0;9192failures+=Tests.test("Math.getExponent(float)", f,93Math.getExponent(f), expected);94failures+=Tests.test("Math.getExponent(float)", minus_f,95Math.getExponent(minus_f), expected);9697failures+=Tests.test("StrictMath.getExponent(float)", f,98StrictMath.getExponent(f), expected);99failures+=Tests.test("StrictMath.getExponent(float)", minus_f,100StrictMath.getExponent(minus_f), expected);101return failures;102}103104/*105* Test Math.getExponent and StrictMath.getExponent with +d and -d.106*/107static int testGetExponentCase(double d, int expected) {108double minus_d = -d;109int failures=0;110111failures+=Tests.test("Math.getExponent(double)", d,112Math.getExponent(d), expected);113failures+=Tests.test("Math.getExponent(double)", minus_d,114Math.getExponent(minus_d), expected);115116failures+=Tests.test("StrictMath.getExponent(double)", d,117StrictMath.getExponent(d), expected);118failures+=Tests.test("StrictMath.getExponent(double)", minus_d,119StrictMath.getExponent(minus_d), expected);120return failures;121}122123public static int testFloatGetExponent() {124int failures = 0;125float [] specialValues = {NaNf,126Float.POSITIVE_INFINITY,127+0.0f,128+1.0f,129+2.0f,130+16.0f,131+Float.MIN_VALUE,132+Float_MAX_SUBNORMAL,133+FloatConsts.MIN_NORMAL,134+Float.MAX_VALUE135};136137int [] specialResults = {Float.MAX_EXPONENT + 1, // NaN results138Float.MAX_EXPONENT + 1, // Infinite results139Float.MIN_EXPONENT - 1, // Zero results1400,1411,1424,143FloatConsts.MIN_EXPONENT - 1,144-FloatConsts.MAX_EXPONENT,145FloatConsts.MIN_EXPONENT,146FloatConsts.MAX_EXPONENT147};148149// Special value tests150for(int i = 0; i < specialValues.length; i++) {151failures += testGetExponentCase(specialValues[i], specialResults[i]);152}153154155// Normal exponent tests156for(int i = FloatConsts.MIN_EXPONENT; i <= FloatConsts.MAX_EXPONENT; i++) {157int result;158159// Create power of two160float po2 = powerOfTwoF(i);161162failures += testGetExponentCase(po2, i);163164// Generate some random bit patterns for the significand165for(int j = 0; j < 10; j++) {166int randSignif = rand.nextInt();167float randFloat;168169randFloat = Float.intBitsToFloat( // Exponent170(Float.floatToIntBits(po2)&171(~FloatConsts.SIGNIF_BIT_MASK)) |172// Significand173(randSignif &174FloatConsts.SIGNIF_BIT_MASK) );175176failures += testGetExponentCase(randFloat, i);177}178179if (i > FloatConsts.MIN_EXPONENT) {180float po2minus = Math.nextAfter(po2,181Float.NEGATIVE_INFINITY);182failures += testGetExponentCase(po2minus, i-1);183}184}185186// Subnormal exponent tests187188/*189* Start with MIN_VALUE, left shift, test high value, low190* values, and random in between.191*192* Use nextAfter to calculate, high value of previous binade,193* loop count i will indicate how many random bits, if any are194* needed.195*/196197float top=Float.MIN_VALUE;198for( int i = 1;199i < FloatConsts.SIGNIFICAND_WIDTH;200i++, top *= 2.0f) {201202failures += testGetExponentCase(top,203FloatConsts.MIN_EXPONENT - 1);204205// Test largest value in next smaller binade206if (i >= 3) {// (i == 1) would test 0.0;207// (i == 2) would just retest MIN_VALUE208testGetExponentCase(Math.nextAfter(top, 0.0f),209FloatConsts.MIN_EXPONENT - 1);210211if( i >= 10) {212// create a bit mask with (i-1) 1's in the low order213// bits214int mask = ~((~0)<<(i-1));215float randFloat = Float.intBitsToFloat( // Exponent216Float.floatToIntBits(top) |217// Significand218(rand.nextInt() & mask ) ) ;219220failures += testGetExponentCase(randFloat,221FloatConsts.MIN_EXPONENT - 1);222}223}224}225226return failures;227}228229230public static int testDoubleGetExponent() {231int failures = 0;232double [] specialValues = {NaNd,233infinityD,234+0.0,235+1.0,236+2.0,237+16.0,238+Double.MIN_VALUE,239+Double_MAX_SUBNORMAL,240+DoubleConsts.MIN_NORMAL,241+Double.MAX_VALUE242};243244int [] specialResults = {Double.MAX_EXPONENT + 1, // NaN results245Double.MAX_EXPONENT + 1, // Infinite results246Double.MIN_EXPONENT - 1, // Zero results2470,2481,2494,250DoubleConsts.MIN_EXPONENT - 1,251-DoubleConsts.MAX_EXPONENT,252DoubleConsts.MIN_EXPONENT,253DoubleConsts.MAX_EXPONENT254};255256// Special value tests257for(int i = 0; i < specialValues.length; i++) {258failures += testGetExponentCase(specialValues[i], specialResults[i]);259}260261262// Normal exponent tests263for(int i = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.MAX_EXPONENT; i++) {264int result;265266// Create power of two267double po2 = powerOfTwoD(i);268269failures += testGetExponentCase(po2, i);270271// Generate some random bit patterns for the significand272for(int j = 0; j < 10; j++) {273long randSignif = rand.nextLong();274double randFloat;275276randFloat = Double.longBitsToDouble( // Exponent277(Double.doubleToLongBits(po2)&278(~DoubleConsts.SIGNIF_BIT_MASK)) |279// Significand280(randSignif &281DoubleConsts.SIGNIF_BIT_MASK) );282283failures += testGetExponentCase(randFloat, i);284}285286if (i > DoubleConsts.MIN_EXPONENT) {287double po2minus = Math.nextAfter(po2,288Double.NEGATIVE_INFINITY);289failures += testGetExponentCase(po2minus, i-1);290}291}292293// Subnormal exponent tests294295/*296* Start with MIN_VALUE, left shift, test high value, low297* values, and random in between.298*299* Use nextAfter to calculate, high value of previous binade;300* loop count i will indicate how many random bits, if any are301* needed.302*/303304double top=Double.MIN_VALUE;305for( int i = 1;306i < DoubleConsts.SIGNIFICAND_WIDTH;307i++, top *= 2.0f) {308309failures += testGetExponentCase(top,310DoubleConsts.MIN_EXPONENT - 1);311312// Test largest value in next smaller binade313if (i >= 3) {// (i == 1) would test 0.0;314// (i == 2) would just retest MIN_VALUE315testGetExponentCase(Math.nextAfter(top, 0.0),316DoubleConsts.MIN_EXPONENT - 1);317318if( i >= 10) {319// create a bit mask with (i-1) 1's in the low order320// bits321long mask = ~((~0L)<<(i-1));322double randFloat = Double.longBitsToDouble( // Exponent323Double.doubleToLongBits(top) |324// Significand325(rand.nextLong() & mask ) ) ;326327failures += testGetExponentCase(randFloat,328DoubleConsts.MIN_EXPONENT - 1);329}330}331}332333return failures;334}335336337/* ******************** nextAfter tests ****************************** */338339static int testNextAfterCase(float start, double direction, float expected) {340int failures=0;341float minus_start = -start;342double minus_direction = -direction;343float minus_expected = -expected;344345failures+=Tests.test("Math.nextAfter(float,double)", start, direction,346Math.nextAfter(start, direction), expected);347failures+=Tests.test("Math.nextAfter(float,double)", minus_start, minus_direction,348Math.nextAfter(minus_start, minus_direction), minus_expected);349350failures+=Tests.test("StrictMath.nextAfter(float,double)", start, direction,351StrictMath.nextAfter(start, direction), expected);352failures+=Tests.test("StrictMath.nextAfter(float,double)", minus_start, minus_direction,353StrictMath.nextAfter(minus_start, minus_direction), minus_expected);354return failures;355}356357static int testNextAfterCase(double start, double direction, double expected) {358int failures=0;359360double minus_start = -start;361double minus_direction = -direction;362double minus_expected = -expected;363364failures+=Tests.test("Math.nextAfter(double,double)", start, direction,365Math.nextAfter(start, direction), expected);366failures+=Tests.test("Math.nextAfter(double,double)", minus_start, minus_direction,367Math.nextAfter(minus_start, minus_direction), minus_expected);368369failures+=Tests.test("StrictMath.nextAfter(double,double)", start, direction,370StrictMath.nextAfter(start, direction), expected);371failures+=Tests.test("StrictMath.nextAfter(double,double)", minus_start, minus_direction,372StrictMath.nextAfter(minus_start, minus_direction), minus_expected);373return failures;374}375376public static int testFloatNextAfter() {377int failures=0;378379/*380* Each row of the testCases matrix represents one test case381* for nexAfter; given the input of the first two columns, the382* result in the last column is expected.383*/384float [][] testCases = {385{NaNf, NaNf, NaNf},386{NaNf, 0.0f, NaNf},387{0.0f, NaNf, NaNf},388{NaNf, infinityF, NaNf},389{infinityF, NaNf, NaNf},390391{infinityF, infinityF, infinityF},392{infinityF, -infinityF, Float.MAX_VALUE},393{infinityF, 0.0f, Float.MAX_VALUE},394395{Float.MAX_VALUE, infinityF, infinityF},396{Float.MAX_VALUE, -infinityF, Float_MAX_VALUEmm},397{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE},398{Float.MAX_VALUE, 0.0f, Float_MAX_VALUEmm},399400{Float_MAX_VALUEmm, Float.MAX_VALUE, Float.MAX_VALUE},401{Float_MAX_VALUEmm, infinityF, Float.MAX_VALUE},402{Float_MAX_VALUEmm, Float_MAX_VALUEmm, Float_MAX_VALUEmm},403404{FloatConsts.MIN_NORMAL, infinityF, FloatConsts.MIN_NORMAL+405Float.MIN_VALUE},406{FloatConsts.MIN_NORMAL, -infinityF, Float_MAX_SUBNORMAL},407{FloatConsts.MIN_NORMAL, 1.0f, FloatConsts.MIN_NORMAL+408Float.MIN_VALUE},409{FloatConsts.MIN_NORMAL, -1.0f, Float_MAX_SUBNORMAL},410{FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL},411412{Float_MAX_SUBNORMAL, FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL},413{Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL},414{Float_MAX_SUBNORMAL, 0.0f, Float_MAX_SUBNORMALmm},415416{Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL},417{Float_MAX_SUBNORMALmm, 0.0f, Float_MAX_SUBNORMALmm-Float.MIN_VALUE},418{Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMALmm},419420{Float.MIN_VALUE, 0.0f, 0.0f},421{-Float.MIN_VALUE, 0.0f, -0.0f},422{Float.MIN_VALUE, Float.MIN_VALUE, Float.MIN_VALUE},423{Float.MIN_VALUE, 1.0f, 2*Float.MIN_VALUE},424425// Make sure zero behavior is tested426{0.0f, 0.0f, 0.0f},427{0.0f, -0.0f, -0.0f},428{-0.0f, 0.0f, 0.0f},429{-0.0f, -0.0f, -0.0f},430{0.0f, infinityF, Float.MIN_VALUE},431{0.0f, -infinityF, -Float.MIN_VALUE},432{-0.0f, infinityF, Float.MIN_VALUE},433{-0.0f, -infinityF, -Float.MIN_VALUE},434{0.0f, Float.MIN_VALUE, 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};439440for(int i = 0; i < testCases.length; i++) {441failures += testNextAfterCase(testCases[i][0], testCases[i][1],442testCases[i][2]);443}444445return failures;446}447448public static int testDoubleNextAfter() {449int failures =0;450451/*452* Each row of the testCases matrix represents one test case453* for nexAfter; given the input of the first two columns, the454* result in the last column is expected.455*/456double [][] testCases = {457{NaNd, NaNd, NaNd},458{NaNd, 0.0d, NaNd},459{0.0d, NaNd, NaNd},460{NaNd, infinityD, NaNd},461{infinityD, NaNd, NaNd},462463{infinityD, infinityD, infinityD},464{infinityD, -infinityD, Double.MAX_VALUE},465{infinityD, 0.0d, Double.MAX_VALUE},466467{Double.MAX_VALUE, infinityD, infinityD},468{Double.MAX_VALUE, -infinityD, Double_MAX_VALUEmm},469{Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE},470{Double.MAX_VALUE, 0.0d, Double_MAX_VALUEmm},471472{Double_MAX_VALUEmm, Double.MAX_VALUE, Double.MAX_VALUE},473{Double_MAX_VALUEmm, infinityD, Double.MAX_VALUE},474{Double_MAX_VALUEmm, Double_MAX_VALUEmm, Double_MAX_VALUEmm},475476{DoubleConsts.MIN_NORMAL, infinityD, DoubleConsts.MIN_NORMAL+477Double.MIN_VALUE},478{DoubleConsts.MIN_NORMAL, -infinityD, Double_MAX_SUBNORMAL},479{DoubleConsts.MIN_NORMAL, 1.0f, DoubleConsts.MIN_NORMAL+480Double.MIN_VALUE},481{DoubleConsts.MIN_NORMAL, -1.0f, Double_MAX_SUBNORMAL},482{DoubleConsts.MIN_NORMAL, DoubleConsts.MIN_NORMAL,DoubleConsts.MIN_NORMAL},483484{Double_MAX_SUBNORMAL, DoubleConsts.MIN_NORMAL,DoubleConsts.MIN_NORMAL},485{Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL},486{Double_MAX_SUBNORMAL, 0.0d, Double_MAX_SUBNORMALmm},487488{Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL},489{Double_MAX_SUBNORMALmm, 0.0d, Double_MAX_SUBNORMALmm-Double.MIN_VALUE},490{Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm},491492{Double.MIN_VALUE, 0.0d, 0.0d},493{-Double.MIN_VALUE, 0.0d, -0.0d},494{Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE},495{Double.MIN_VALUE, 1.0f, 2*Double.MIN_VALUE},496497// Make sure zero behavior is tested498{0.0d, 0.0d, 0.0d},499{0.0d, -0.0d, -0.0d},500{-0.0d, 0.0d, 0.0d},501{-0.0d, -0.0d, -0.0d},502{0.0d, infinityD, Double.MIN_VALUE},503{0.0d, -infinityD, -Double.MIN_VALUE},504{-0.0d, infinityD, Double.MIN_VALUE},505{-0.0d, -infinityD, -Double.MIN_VALUE},506{0.0d, Double.MIN_VALUE, 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};511512for(int i = 0; i < testCases.length; i++) {513failures += testNextAfterCase(testCases[i][0], testCases[i][1],514testCases[i][2]);515}516return failures;517}518519/* ******************** nextUp tests ********************************* */520521public static int testFloatNextUp() {522int failures=0;523524/*525* Each row of testCases represents one test case for nextUp;526* the first column is the input and the second column is the527* expected result.528*/529float testCases [][] = {530{NaNf, NaNf},531{-infinityF, -Float.MAX_VALUE},532{-Float.MAX_VALUE, -Float_MAX_VALUEmm},533{-FloatConsts.MIN_NORMAL, -Float_MAX_SUBNORMAL},534{-Float_MAX_SUBNORMAL, -Float_MAX_SUBNORMALmm},535{-Float.MIN_VALUE, -0.0f},536{-0.0f, Float.MIN_VALUE},537{+0.0f, Float.MIN_VALUE},538{Float.MIN_VALUE, Float.MIN_VALUE*2},539{Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMAL},540{Float_MAX_SUBNORMAL, FloatConsts.MIN_NORMAL},541{FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL+Float.MIN_VALUE},542{Float_MAX_VALUEmm, Float.MAX_VALUE},543{Float.MAX_VALUE, infinityF},544{infinityF, infinityF}545};546547for(int i = 0; i < testCases.length; i++) {548failures+=Tests.test("Math.nextUp(float)",549testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);550551failures+=Tests.test("StrictMath.nextUp(float)",552testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);553}554555return failures;556}557558559public static int testDoubleNextUp() {560int failures=0;561562/*563* Each row of testCases represents one test case for nextUp;564* the first column is the input and the second column is the565* expected result.566*/567double testCases [][] = {568{NaNd, NaNd},569{-infinityD, -Double.MAX_VALUE},570{-Double.MAX_VALUE, -Double_MAX_VALUEmm},571{-DoubleConsts.MIN_NORMAL, -Double_MAX_SUBNORMAL},572{-Double_MAX_SUBNORMAL, -Double_MAX_SUBNORMALmm},573{-Double.MIN_VALUE, -0.0d},574{-0.0d, Double.MIN_VALUE},575{+0.0d, Double.MIN_VALUE},576{Double.MIN_VALUE, Double.MIN_VALUE*2},577{Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMAL},578{Double_MAX_SUBNORMAL, DoubleConsts.MIN_NORMAL},579{DoubleConsts.MIN_NORMAL, DoubleConsts.MIN_NORMAL+Double.MIN_VALUE},580{Double_MAX_VALUEmm, Double.MAX_VALUE},581{Double.MAX_VALUE, infinityD},582{infinityD, infinityD}583};584585for(int i = 0; i < testCases.length; i++) {586failures+=Tests.test("Math.nextUp(double)",587testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);588589failures+=Tests.test("StrictMath.nextUp(double)",590testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);591}592593return failures;594}595596/* ******************** nextDown tests ********************************* */597598public static int testFloatNextDown() {599int failures=0;600601/*602* Each row of testCases represents one test case for nextDown;603* the first column is the input and the second column is the604* expected result.605*/606float testCases [][] = {607{NaNf, NaNf},608{-infinityF, -infinityF},609{-Float.MAX_VALUE, -infinityF},610{-Float_MAX_VALUEmm, -Float.MAX_VALUE},611{-Float_MAX_SUBNORMAL, -FloatConsts.MIN_NORMAL},612{-Float_MAX_SUBNORMALmm, -Float_MAX_SUBNORMAL},613{-0.0f, -Float.MIN_VALUE},614{+0.0f, -Float.MIN_VALUE},615{Float.MIN_VALUE, 0.0f},616{Float.MIN_VALUE*2, Float.MIN_VALUE},617{Float_MAX_SUBNORMAL, Float_MAX_SUBNORMALmm},618{FloatConsts.MIN_NORMAL, Float_MAX_SUBNORMAL},619{FloatConsts.MIN_NORMAL+620Float.MIN_VALUE, FloatConsts.MIN_NORMAL},621{Float.MAX_VALUE, Float_MAX_VALUEmm},622{infinityF, Float.MAX_VALUE},623};624625for(int i = 0; i < testCases.length; i++) {626failures+=Tests.test("Math.nextDown(float)",627testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]);628629failures+=Tests.test("StrictMath.nextDown(float)",630testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]);631}632633return failures;634}635636637public static int testDoubleNextDown() {638int failures=0;639640/*641* Each row of testCases represents one test case for nextDown;642* the first column is the input and the second column is the643* expected result.644*/645double testCases [][] = {646{NaNd, NaNd},647{-infinityD, -infinityD},648{-Double.MAX_VALUE, -infinityD},649{-Double_MAX_VALUEmm, -Double.MAX_VALUE},650{-Double_MAX_SUBNORMAL, -DoubleConsts.MIN_NORMAL},651{-Double_MAX_SUBNORMALmm, -Double_MAX_SUBNORMAL},652{-0.0d, -Double.MIN_VALUE},653{+0.0d, -Double.MIN_VALUE},654{Double.MIN_VALUE, 0.0d},655{Double.MIN_VALUE*2, Double.MIN_VALUE},656{Double_MAX_SUBNORMAL, Double_MAX_SUBNORMALmm},657{DoubleConsts.MIN_NORMAL, Double_MAX_SUBNORMAL},658{DoubleConsts.MIN_NORMAL+659Double.MIN_VALUE, DoubleConsts.MIN_NORMAL},660{Double.MAX_VALUE, Double_MAX_VALUEmm},661{infinityD, Double.MAX_VALUE},662};663664for(int i = 0; i < testCases.length; i++) {665failures+=Tests.test("Math.nextDown(double)",666testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]);667668failures+=Tests.test("StrictMath.nextDown(double)",669testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]);670}671672return failures;673}674675676/* ********************** boolean tests ****************************** */677678/*679* Combined tests for boolean functions, isFinite, isInfinite,680* isNaN, isUnordered.681*/682683public static int testFloatBooleanMethods() {684int failures = 0;685686float testCases [] = {687NaNf,688-infinityF,689infinityF,690-Float.MAX_VALUE,691-3.0f,692-1.0f,693-FloatConsts.MIN_NORMAL,694-Float_MAX_SUBNORMALmm,695-Float_MAX_SUBNORMAL,696-Float.MIN_VALUE,697-0.0f,698+0.0f,699Float.MIN_VALUE,700Float_MAX_SUBNORMALmm,701Float_MAX_SUBNORMAL,702FloatConsts.MIN_NORMAL,7031.0f,7043.0f,705Float_MAX_VALUEmm,706Float.MAX_VALUE707};708709for(int i = 0; i < testCases.length; i++) {710// isNaN711failures+=Tests.test("FpUtils.isNaN(float)", testCases[i],712FpUtils.isNaN(testCases[i]), (i ==0));713714// isFinite715failures+=Tests.test("Float.isFinite(float)", testCases[i],716Float.isFinite(testCases[i]), (i >= 3));717718// isInfinite719failures+=Tests.test("FpUtils.isInfinite(float)", testCases[i],720FpUtils.isInfinite(testCases[i]), (i==1 || i==2));721722// isUnorderd723for(int j = 0; j < testCases.length; j++) {724failures+=Tests.test("FpUtils.isUnordered(float, float)", testCases[i],testCases[j],725FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));726}727}728729return failures;730}731732public static int testDoubleBooleanMethods() {733int failures = 0;734boolean result = false;735736double testCases [] = {737NaNd,738-infinityD,739infinityD,740-Double.MAX_VALUE,741-3.0d,742-1.0d,743-DoubleConsts.MIN_NORMAL,744-Double_MAX_SUBNORMALmm,745-Double_MAX_SUBNORMAL,746-Double.MIN_VALUE,747-0.0d,748+0.0d,749Double.MIN_VALUE,750Double_MAX_SUBNORMALmm,751Double_MAX_SUBNORMAL,752DoubleConsts.MIN_NORMAL,7531.0d,7543.0d,755Double_MAX_VALUEmm,756Double.MAX_VALUE757};758759for(int i = 0; i < testCases.length; i++) {760// isNaN761failures+=Tests.test("FpUtils.isNaN(double)", testCases[i],762FpUtils.isNaN(testCases[i]), (i ==0));763764// isFinite765failures+=Tests.test("Double.isFinite(double)", testCases[i],766Double.isFinite(testCases[i]), (i >= 3));767768// isInfinite769failures+=Tests.test("FpUtils.isInfinite(double)", testCases[i],770FpUtils.isInfinite(testCases[i]), (i==1 || i==2));771772// isUnorderd773for(int j = 0; j < testCases.length; j++) {774failures+=Tests.test("FpUtils.isUnordered(double, double)", testCases[i],testCases[j],775FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));776}777}778779return failures;780}781782/* ******************** copySign tests******************************** */783784public static int testFloatCopySign() {785int failures = 0;786787// testCases[0] are logically positive numbers;788// testCases[1] are negative numbers.789float testCases [][] = {790{+0.0f,791Float.MIN_VALUE,792Float_MAX_SUBNORMALmm,793Float_MAX_SUBNORMAL,794FloatConsts.MIN_NORMAL,7951.0f,7963.0f,797Float_MAX_VALUEmm,798Float.MAX_VALUE,799infinityF,800},801{-infinityF,802-Float.MAX_VALUE,803-3.0f,804-1.0f,805-FloatConsts.MIN_NORMAL,806-Float_MAX_SUBNORMALmm,807-Float_MAX_SUBNORMAL,808-Float.MIN_VALUE,809-0.0f}810};811812float NaNs[] = {Float.intBitsToFloat(0x7fc00000), // "positive" NaN813Float.intBitsToFloat(0xFfc00000)}; // "negative" NaN814815// Tests shared between raw and non-raw versions816for(int i = 0; i < 2; i++) {817for(int j = 0; j < 2; j++) {818for(int m = 0; m < testCases[i].length; m++) {819for(int n = 0; n < testCases[j].length; n++) {820// copySign(magnitude, sign)821failures+=Tests.test("Math.copySign(float,float)",822testCases[i][m],testCases[j][n],823Math.copySign(testCases[i][m], testCases[j][n]),824(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );825826failures+=Tests.test("StrictMath.copySign(float,float)",827testCases[i][m],testCases[j][n],828StrictMath.copySign(testCases[i][m], testCases[j][n]),829(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );830}831}832}833}834835// For rawCopySign, NaN may effectively have either sign bit836// while for copySign NaNs are treated as if they always have837// a zero sign bit (i.e. as positive numbers)838for(int i = 0; i < 2; i++) {839for(int j = 0; j < NaNs.length; j++) {840for(int m = 0; m < testCases[i].length; m++) {841// copySign(magnitude, sign)842843failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==844Math.abs(testCases[i][m])) ? 0:1;845846847failures+=Tests.test("StrictMath.copySign(float,float)",848testCases[i][m], NaNs[j],849StrictMath.copySign(testCases[i][m], NaNs[j]),850Math.abs(testCases[i][m]) );851}852}853}854855return failures;856}857858public static int testDoubleCopySign() {859int failures = 0;860861// testCases[0] are logically positive numbers;862// testCases[1] are negative numbers.863double testCases [][] = {864{+0.0d,865Double.MIN_VALUE,866Double_MAX_SUBNORMALmm,867Double_MAX_SUBNORMAL,868DoubleConsts.MIN_NORMAL,8691.0d,8703.0d,871Double_MAX_VALUEmm,872Double.MAX_VALUE,873infinityD,874},875{-infinityD,876-Double.MAX_VALUE,877-3.0d,878-1.0d,879-DoubleConsts.MIN_NORMAL,880-Double_MAX_SUBNORMALmm,881-Double_MAX_SUBNORMAL,882-Double.MIN_VALUE,883-0.0d}884};885886double NaNs[] = {Double.longBitsToDouble(0x7ff8000000000000L), // "positive" NaN887Double.longBitsToDouble(0xfff8000000000000L), // "negative" NaN888Double.longBitsToDouble(0x7FF0000000000001L),889Double.longBitsToDouble(0xFFF0000000000001L),890Double.longBitsToDouble(0x7FF8555555555555L),891Double.longBitsToDouble(0xFFF8555555555555L),892Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),893Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),894Double.longBitsToDouble(0x7FFDeadBeef00000L),895Double.longBitsToDouble(0xFFFDeadBeef00000L),896Double.longBitsToDouble(0x7FFCafeBabe00000L),897Double.longBitsToDouble(0xFFFCafeBabe00000L)};898899// Tests shared between Math and StrictMath versions900for(int i = 0; i < 2; i++) {901for(int j = 0; j < 2; j++) {902for(int m = 0; m < testCases[i].length; m++) {903for(int n = 0; n < testCases[j].length; n++) {904// copySign(magnitude, sign)905failures+=Tests.test("MathcopySign(double,double)",906testCases[i][m],testCases[j][n],907Math.copySign(testCases[i][m], testCases[j][n]),908(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );909910failures+=Tests.test("StrictMath.copySign(double,double)",911testCases[i][m],testCases[j][n],912StrictMath.copySign(testCases[i][m], testCases[j][n]),913(j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );914}915}916}917}918919// For Math.copySign, NaN may effectively have either sign bit920// while for StrictMath.copySign NaNs are treated as if they921// always have a zero sign bit (i.e. as positive numbers)922for(int i = 0; i < 2; i++) {923for(int j = 0; j < NaNs.length; j++) {924for(int m = 0; m < testCases[i].length; m++) {925// copySign(magnitude, sign)926927failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==928Math.abs(testCases[i][m])) ? 0:1;929930931failures+=Tests.test("StrictMath.copySign(double,double)",932testCases[i][m], NaNs[j],933StrictMath.copySign(testCases[i][m], NaNs[j]),934Math.abs(testCases[i][m]) );935}936}937}938939940return failures;941}942943/* ************************ scalb tests ******************************* */944945static int testScalbCase(float value, int scale_factor, float expected) {946int failures=0;947948failures+=Tests.test("Math.scalb(float,int)",949value, scale_factor,950Math.scalb(value, scale_factor), expected);951952failures+=Tests.test("Math.scalb(float,int)",953-value, scale_factor,954Math.scalb(-value, scale_factor), -expected);955956failures+=Tests.test("StrictMath.scalb(float,int)",957value, scale_factor,958StrictMath.scalb(value, scale_factor), expected);959960failures+=Tests.test("StrictMath.scalb(float,int)",961-value, scale_factor,962StrictMath.scalb(-value, scale_factor), -expected);963return failures;964}965966public static int testFloatScalb() {967int failures=0;968int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT +969FloatConsts.SIGNIFICAND_WIDTH + 1;970971972// Arguments x, where scalb(x,n) is x for any n.973float [] identityTestCases = {NaNf,974-0.0f,975+0.0f,976infinityF,977-infinityF978};979980float [] subnormalTestCases = {981Float.MIN_VALUE,9823.0f*Float.MIN_VALUE,983Float_MAX_SUBNORMALmm,984Float_MAX_SUBNORMAL985};986987float [] someTestCases = {988Float.MIN_VALUE,9893.0f*Float.MIN_VALUE,990Float_MAX_SUBNORMALmm,991Float_MAX_SUBNORMAL,992FloatConsts.MIN_NORMAL,9931.0f,9942.0f,9953.0f,996(float)Math.PI,997Float_MAX_VALUEmm,998Float.MAX_VALUE999};10001001int [] oneMultiplyScalingFactors = {1002FloatConsts.MIN_EXPONENT,1003FloatConsts.MIN_EXPONENT+1,1004-3,1005-2,1006-1,10070,10081,10092,10103,1011FloatConsts.MAX_EXPONENT-1,1012FloatConsts.MAX_EXPONENT1013};10141015int [] manyScalingFactors = {1016Integer.MIN_VALUE,1017Integer.MIN_VALUE+1,1018-MAX_SCALE -1,1019-MAX_SCALE,1020-MAX_SCALE+1,102110222*FloatConsts.MIN_EXPONENT-1, // -25310232*FloatConsts.MIN_EXPONENT, // -25210242*FloatConsts.MIN_EXPONENT+1, // -25110251026FpUtils.ilogb(Float.MIN_VALUE)-1, // -1501027FpUtils.ilogb(Float.MIN_VALUE), // -1491028-FloatConsts.MAX_EXPONENT, // -1271029FloatConsts.MIN_EXPONENT, // -12610301031-2,1032-1,10330,10341,10352,10361037FloatConsts.MAX_EXPONENT-1, // 1261038FloatConsts.MAX_EXPONENT, // 1271039FloatConsts.MAX_EXPONENT+1, // 128104010412*FloatConsts.MAX_EXPONENT-1, // 25310422*FloatConsts.MAX_EXPONENT, // 25410432*FloatConsts.MAX_EXPONENT+1, // 25510441045MAX_SCALE-1,1046MAX_SCALE,1047MAX_SCALE+1,1048Integer.MAX_VALUE-1,1049Integer.MAX_VALUE1050};10511052// Test cases where scaling is always a no-op1053for(int i=0; i < identityTestCases.length; i++) {1054for(int j=0; j < manyScalingFactors.length; j++) {1055failures += testScalbCase(identityTestCases[i],1056manyScalingFactors[j],1057identityTestCases[i]);1058}1059}10601061// Test cases where result is 0.0 or infinity due to magnitude1062// of the scaling factor1063for(int i=0; i < someTestCases.length; i++) {1064for(int j=0; j < manyScalingFactors.length; j++) {1065int scaleFactor = manyScalingFactors[j];1066if (Math.abs(scaleFactor) >= MAX_SCALE) {1067float value = someTestCases[i];1068failures+=testScalbCase(value,1069scaleFactor,1070Math.copySign( (scaleFactor>0?infinityF:0.0f), value) );1071}1072}1073}10741075// Test cases that could be done with one floating-point1076// multiply.1077for(int i=0; i < someTestCases.length; i++) {1078for(int j=0; j < oneMultiplyScalingFactors.length; j++) {1079int scaleFactor = oneMultiplyScalingFactors[j];1080float value = someTestCases[i];10811082failures+=testScalbCase(value,1083scaleFactor,1084value*powerOfTwoF(scaleFactor));1085}1086}10871088// Create 2^MAX_EXPONENT1089float twoToTheMaxExp = 1.0f; // 2^01090for(int i = 0; i < FloatConsts.MAX_EXPONENT; i++)1091twoToTheMaxExp *=2.0f;10921093// Scale-up subnormal values until they all overflow1094for(int i=0; i < subnormalTestCases.length; i++) {1095float scale = 1.0f; // 2^j1096float value = subnormalTestCases[i];10971098for(int j=FloatConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow1099int scaleFactor = j;11001101failures+=testScalbCase(value,1102scaleFactor,1103(FpUtils.ilogb(value) +j > FloatConsts.MAX_EXPONENT ) ?1104Math.copySign(infinityF, value) : // overflow1105// calculate right answer1106twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );1107scale*=2.0f;1108}1109}11101111// Scale down a large number until it underflows. By scaling1112// down MAX_NORMALmm, the first subnormal result will be exact1113// but the next one will round -- all those results can be1114// checked by halving a separate value in the loop. Actually,1115// we can keep halving and checking until the product is zero1116// since:1117//1118// 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact1119// it will round *up*1120//1121// 2. When rounding first occurs in the expected product, it1122// too rounds up, to 2^-MAX_EXPONENT.1123//1124// Halving expected after rounding happends to give the same1125// result as the scalb operation.1126float expected = Float_MAX_VALUEmm *0.5f;1127for(int i = -1; i > -MAX_SCALE; i--) {1128failures+=testScalbCase(Float_MAX_VALUEmm, i, expected);11291130expected *= 0.5f;1131}11321133// Tricky rounding tests:1134// Scale down a large number into subnormal range such that if1135// scalb is being implemented with multiple floating-point1136// multiplies, the value would round twice if the multiplies1137// were done in the wrong order.11381139float value = 0x8.0000bP-5f;1140expected = 0x1.00001p-129f;11411142for(int i = 0; i < 129; i++) {1143failures+=testScalbCase(value,1144-127-i,1145expected);1146value *=2.0f;1147}11481149return failures;1150}11511152static int testScalbCase(double value, int scale_factor, double expected) {1153int failures=0;11541155failures+=Tests.test("Math.scalb(double,int)",1156value, scale_factor,1157Math.scalb(value, scale_factor), expected);11581159failures+=Tests.test("Math.scalb(double,int)",1160-value, scale_factor,1161Math.scalb(-value, scale_factor), -expected);11621163failures+=Tests.test("StrictMath.scalb(double,int)",1164value, scale_factor,1165StrictMath.scalb(value, scale_factor), expected);11661167failures+=Tests.test("StrictMath.scalb(double,int)",1168-value, scale_factor,1169StrictMath.scalb(-value, scale_factor), -expected);11701171return failures;1172}11731174public static int testDoubleScalb() {1175int failures=0;1176int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT +1177DoubleConsts.SIGNIFICAND_WIDTH + 1;117811791180// Arguments x, where scalb(x,n) is x for any n.1181double [] identityTestCases = {NaNd,1182-0.0,1183+0.0,1184infinityD,1185};11861187double [] subnormalTestCases = {1188Double.MIN_VALUE,11893.0d*Double.MIN_VALUE,1190Double_MAX_SUBNORMALmm,1191Double_MAX_SUBNORMAL1192};11931194double [] someTestCases = {1195Double.MIN_VALUE,11963.0d*Double.MIN_VALUE,1197Double_MAX_SUBNORMALmm,1198Double_MAX_SUBNORMAL,1199DoubleConsts.MIN_NORMAL,12001.0d,12012.0d,12023.0d,1203Math.PI,1204Double_MAX_VALUEmm,1205Double.MAX_VALUE1206};12071208int [] oneMultiplyScalingFactors = {1209DoubleConsts.MIN_EXPONENT,1210DoubleConsts.MIN_EXPONENT+1,1211-3,1212-2,1213-1,12140,12151,12162,12173,1218DoubleConsts.MAX_EXPONENT-1,1219DoubleConsts.MAX_EXPONENT1220};12211222int [] manyScalingFactors = {1223Integer.MIN_VALUE,1224Integer.MIN_VALUE+1,1225-MAX_SCALE -1,1226-MAX_SCALE,1227-MAX_SCALE+1,122812292*DoubleConsts.MIN_EXPONENT-1, // -204512302*DoubleConsts.MIN_EXPONENT, // -204412312*DoubleConsts.MIN_EXPONENT+1, // -204312321233FpUtils.ilogb(Double.MIN_VALUE)-1, // -10761234FpUtils.ilogb(Double.MIN_VALUE), // -10751235-DoubleConsts.MAX_EXPONENT, // -10231236DoubleConsts.MIN_EXPONENT, // -102212371238-2,1239-1,12400,12411,12422,12431244DoubleConsts.MAX_EXPONENT-1, // 10221245DoubleConsts.MAX_EXPONENT, // 10231246DoubleConsts.MAX_EXPONENT+1, // 1024124712482*DoubleConsts.MAX_EXPONENT-1, // 204512492*DoubleConsts.MAX_EXPONENT, // 204612502*DoubleConsts.MAX_EXPONENT+1, // 204712511252MAX_SCALE-1,1253MAX_SCALE,1254MAX_SCALE+1,1255Integer.MAX_VALUE-1,1256Integer.MAX_VALUE1257};12581259// Test cases where scaling is always a no-op1260for(int i=0; i < identityTestCases.length; i++) {1261for(int j=0; j < manyScalingFactors.length; j++) {1262failures += testScalbCase(identityTestCases[i],1263manyScalingFactors[j],1264identityTestCases[i]);1265}1266}12671268// Test cases where result is 0.0 or infinity due to magnitude1269// of the scaling factor1270for(int i=0; i < someTestCases.length; i++) {1271for(int j=0; j < manyScalingFactors.length; j++) {1272int scaleFactor = manyScalingFactors[j];1273if (Math.abs(scaleFactor) >= MAX_SCALE) {1274double value = someTestCases[i];1275failures+=testScalbCase(value,1276scaleFactor,1277Math.copySign( (scaleFactor>0?infinityD:0.0), value) );1278}1279}1280}12811282// Test cases that could be done with one floating-point1283// multiply.1284for(int i=0; i < someTestCases.length; i++) {1285for(int j=0; j < oneMultiplyScalingFactors.length; j++) {1286int scaleFactor = oneMultiplyScalingFactors[j];1287double value = someTestCases[i];12881289failures+=testScalbCase(value,1290scaleFactor,1291value*powerOfTwoD(scaleFactor));1292}1293}12941295// Create 2^MAX_EXPONENT1296double twoToTheMaxExp = 1.0; // 2^01297for(int i = 0; i < DoubleConsts.MAX_EXPONENT; i++)1298twoToTheMaxExp *=2.0;12991300// Scale-up subnormal values until they all overflow1301for(int i=0; i < subnormalTestCases.length; i++) {1302double scale = 1.0; // 2^j1303double value = subnormalTestCases[i];13041305for(int j=DoubleConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow1306int scaleFactor = j;13071308failures+=testScalbCase(value,1309scaleFactor,1310(FpUtils.ilogb(value) +j > DoubleConsts.MAX_EXPONENT ) ?1311Math.copySign(infinityD, value) : // overflow1312// calculate right answer1313twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );1314scale*=2.0;1315}1316}13171318// Scale down a large number until it underflows. By scaling1319// down MAX_NORMALmm, the first subnormal result will be exact1320// but the next one will round -- all those results can be1321// checked by halving a separate value in the loop. Actually,1322// we can keep halving and checking until the product is zero1323// since:1324//1325// 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact1326// it will round *up*1327//1328// 2. When rounding first occurs in the expected product, it1329// too rounds up, to 2^-MAX_EXPONENT.1330//1331// Halving expected after rounding happends to give the same1332// result as the scalb operation.1333double expected = Double_MAX_VALUEmm *0.5f;1334for(int i = -1; i > -MAX_SCALE; i--) {1335failures+=testScalbCase(Double_MAX_VALUEmm, i, expected);13361337expected *= 0.5;1338}13391340// Tricky rounding tests:1341// Scale down a large number into subnormal range such that if1342// scalb is being implemented with multiple floating-point1343// multiplies, the value would round twice if the multiplies1344// were done in the wrong order.13451346double value = 0x1.000000000000bP-1;1347expected = 0x0.2000000000001P-1022;1348for(int i = 0; i < DoubleConsts.MAX_EXPONENT+2; i++) {1349failures+=testScalbCase(value,1350-1024-i,1351expected);1352value *=2.0;1353}13541355return failures;1356}13571358/* ************************* ulp tests ******************************* */135913601361/*1362* Test Math.ulp and StrictMath.ulp with +d and -d.1363*/1364static int testUlpCase(float f, float expected) {1365float minus_f = -f;1366int failures=0;13671368failures+=Tests.test("Math.ulp(float)", f,1369Math.ulp(f), expected);1370failures+=Tests.test("Math.ulp(float)", minus_f,1371Math.ulp(minus_f), expected);1372failures+=Tests.test("StrictMath.ulp(float)", f,1373StrictMath.ulp(f), expected);1374failures+=Tests.test("StrictMath.ulp(float)", minus_f,1375StrictMath.ulp(minus_f), expected);1376return failures;1377}13781379static int testUlpCase(double d, double expected) {1380double minus_d = -d;1381int failures=0;13821383failures+=Tests.test("Math.ulp(double)", d,1384Math.ulp(d), expected);1385failures+=Tests.test("Math.ulp(double)", minus_d,1386Math.ulp(minus_d), expected);1387failures+=Tests.test("StrictMath.ulp(double)", d,1388StrictMath.ulp(d), expected);1389failures+=Tests.test("StrictMath.ulp(double)", minus_d,1390StrictMath.ulp(minus_d), expected);1391return failures;1392}13931394public static int testFloatUlp() {1395int failures = 0;1396float [] specialValues = {NaNf,1397Float.POSITIVE_INFINITY,1398+0.0f,1399+1.0f,1400+2.0f,1401+16.0f,1402+Float.MIN_VALUE,1403+Float_MAX_SUBNORMAL,1404+FloatConsts.MIN_NORMAL,1405+Float.MAX_VALUE1406};14071408float [] specialResults = {NaNf,1409Float.POSITIVE_INFINITY,1410Float.MIN_VALUE,1411powerOfTwoF(-23),1412powerOfTwoF(-22),1413powerOfTwoF(-19),1414Float.MIN_VALUE,1415Float.MIN_VALUE,1416Float.MIN_VALUE,1417powerOfTwoF(104)1418};14191420// Special value tests1421for(int i = 0; i < specialValues.length; i++) {1422failures += testUlpCase(specialValues[i], specialResults[i]);1423}142414251426// Normal exponent tests1427for(int i = FloatConsts.MIN_EXPONENT; i <= FloatConsts.MAX_EXPONENT; i++) {1428float expected;14291430// Create power of two1431float po2 = powerOfTwoF(i);1432expected = Math.scalb(1.0f, i - (FloatConsts.SIGNIFICAND_WIDTH-1));14331434failures += testUlpCase(po2, expected);14351436// Generate some random bit patterns for the significand1437for(int j = 0; j < 10; j++) {1438int randSignif = rand.nextInt();1439float randFloat;14401441randFloat = Float.intBitsToFloat( // Exponent1442(Float.floatToIntBits(po2)&1443(~FloatConsts.SIGNIF_BIT_MASK)) |1444// Significand1445(randSignif &1446FloatConsts.SIGNIF_BIT_MASK) );14471448failures += testUlpCase(randFloat, expected);1449}14501451if (i > FloatConsts.MIN_EXPONENT) {1452float po2minus = Math.nextAfter(po2,1453Float.NEGATIVE_INFINITY);1454failures += testUlpCase(po2minus, expected/2.0f);1455}1456}14571458// Subnormal tests14591460/*1461* Start with MIN_VALUE, left shift, test high value, low1462* values, and random in between.1463*1464* Use nextAfter to calculate, high value of previous binade,1465* loop count i will indicate how many random bits, if any are1466* needed.1467*/14681469float top=Float.MIN_VALUE;1470for( int i = 1;1471i < FloatConsts.SIGNIFICAND_WIDTH;1472i++, top *= 2.0f) {14731474failures += testUlpCase(top, Float.MIN_VALUE);14751476// Test largest value in next smaller binade1477if (i >= 3) {// (i == 1) would test 0.0;1478// (i == 2) would just retest MIN_VALUE1479testUlpCase(Math.nextAfter(top, 0.0f),1480Float.MIN_VALUE);14811482if( i >= 10) {1483// create a bit mask with (i-1) 1's in the low order1484// bits1485int mask = ~((~0)<<(i-1));1486float randFloat = Float.intBitsToFloat( // Exponent1487Float.floatToIntBits(top) |1488// Significand1489(rand.nextInt() & mask ) ) ;14901491failures += testUlpCase(randFloat, Float.MIN_VALUE);1492}1493}1494}14951496return failures;1497}14981499public static int testDoubleUlp() {1500int failures = 0;1501double [] specialValues = {NaNd,1502Double.POSITIVE_INFINITY,1503+0.0d,1504+1.0d,1505+2.0d,1506+16.0d,1507+Double.MIN_VALUE,1508+Double_MAX_SUBNORMAL,1509+DoubleConsts.MIN_NORMAL,1510+Double.MAX_VALUE1511};15121513double [] specialResults = {NaNf,1514Double.POSITIVE_INFINITY,1515Double.MIN_VALUE,1516powerOfTwoD(-52),1517powerOfTwoD(-51),1518powerOfTwoD(-48),1519Double.MIN_VALUE,1520Double.MIN_VALUE,1521Double.MIN_VALUE,1522powerOfTwoD(971)1523};15241525// Special value tests1526for(int i = 0; i < specialValues.length; i++) {1527failures += testUlpCase(specialValues[i], specialResults[i]);1528}152915301531// Normal exponent tests1532for(int i = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.MAX_EXPONENT; i++) {1533double expected;15341535// Create power of two1536double po2 = powerOfTwoD(i);1537expected = Math.scalb(1.0, i - (DoubleConsts.SIGNIFICAND_WIDTH-1));15381539failures += testUlpCase(po2, expected);15401541// Generate some random bit patterns for the significand1542for(int j = 0; j < 10; j++) {1543long randSignif = rand.nextLong();1544double randDouble;15451546randDouble = Double.longBitsToDouble( // Exponent1547(Double.doubleToLongBits(po2)&1548(~DoubleConsts.SIGNIF_BIT_MASK)) |1549// Significand1550(randSignif &1551DoubleConsts.SIGNIF_BIT_MASK) );15521553failures += testUlpCase(randDouble, expected);1554}15551556if (i > DoubleConsts.MIN_EXPONENT) {1557double po2minus = Math.nextAfter(po2,1558Double.NEGATIVE_INFINITY);1559failures += testUlpCase(po2minus, expected/2.0f);1560}1561}15621563// Subnormal tests15641565/*1566* Start with MIN_VALUE, left shift, test high value, low1567* values, and random in between.1568*1569* Use nextAfter to calculate, high value of previous binade,1570* loop count i will indicate how many random bits, if any are1571* needed.1572*/15731574double top=Double.MIN_VALUE;1575for( int i = 1;1576i < DoubleConsts.SIGNIFICAND_WIDTH;1577i++, top *= 2.0f) {15781579failures += testUlpCase(top, Double.MIN_VALUE);15801581// Test largest value in next smaller binade1582if (i >= 3) {// (i == 1) would test 0.0;1583// (i == 2) would just retest MIN_VALUE1584testUlpCase(Math.nextAfter(top, 0.0f),1585Double.MIN_VALUE);15861587if( i >= 10) {1588// create a bit mask with (i-1) 1's in the low order1589// bits1590int mask = ~((~0)<<(i-1));1591double randDouble = Double.longBitsToDouble( // Exponent1592Double.doubleToLongBits(top) |1593// Significand1594(rand.nextLong() & mask ) ) ;15951596failures += testUlpCase(randDouble, Double.MIN_VALUE);1597}1598}1599}16001601return failures;1602}16031604public static int testFloatSignum() {1605int failures = 0;1606float testCases [][] = {1607{NaNf, NaNf},1608{-infinityF, -1.0f},1609{-Float.MAX_VALUE, -1.0f},1610{-FloatConsts.MIN_NORMAL, -1.0f},1611{-1.0f, -1.0f},1612{-2.0f, -1.0f},1613{-Float_MAX_SUBNORMAL, -1.0f},1614{-Float.MIN_VALUE, -1.0f},1615{-0.0f, -0.0f},1616{+0.0f, +0.0f},1617{Float.MIN_VALUE, 1.0f},1618{Float_MAX_SUBNORMALmm, 1.0f},1619{Float_MAX_SUBNORMAL, 1.0f},1620{FloatConsts.MIN_NORMAL, 1.0f},1621{1.0f, 1.0f},1622{2.0f, 1.0f},1623{Float_MAX_VALUEmm, 1.0f},1624{Float.MAX_VALUE, 1.0f},1625{infinityF, 1.0f}1626};16271628for(int i = 0; i < testCases.length; i++) {1629failures+=Tests.test("Math.signum(float)",1630testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);1631failures+=Tests.test("StrictMath.signum(float)",1632testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);1633}16341635return failures;1636}16371638public static int testDoubleSignum() {1639int failures = 0;1640double testCases [][] = {1641{NaNd, NaNd},1642{-infinityD, -1.0},1643{-Double.MAX_VALUE, -1.0},1644{-DoubleConsts.MIN_NORMAL, -1.0},1645{-1.0, -1.0},1646{-2.0, -1.0},1647{-Double_MAX_SUBNORMAL, -1.0},1648{-Double.MIN_VALUE, -1.0d},1649{-0.0d, -0.0d},1650{+0.0d, +0.0d},1651{Double.MIN_VALUE, 1.0},1652{Double_MAX_SUBNORMALmm, 1.0},1653{Double_MAX_SUBNORMAL, 1.0},1654{DoubleConsts.MIN_NORMAL, 1.0},1655{1.0, 1.0},1656{2.0, 1.0},1657{Double_MAX_VALUEmm, 1.0},1658{Double.MAX_VALUE, 1.0},1659{infinityD, 1.0}1660};16611662for(int i = 0; i < testCases.length; i++) {1663failures+=Tests.test("Math.signum(double)",1664testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);1665failures+=Tests.test("StrictMath.signum(double)",1666testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);1667}16681669return failures;1670}167116721673public static void main(String argv[]) {1674int failures = 0;16751676failures += testFloatGetExponent();1677failures += testDoubleGetExponent();16781679failures += testFloatNextAfter();1680failures += testDoubleNextAfter();16811682failures += testFloatNextUp();1683failures += testDoubleNextUp();16841685failures += testFloatNextDown();1686failures += testDoubleNextDown();16871688failures += testFloatBooleanMethods();1689failures += testDoubleBooleanMethods();16901691failures += testFloatCopySign();1692failures += testDoubleCopySign();16931694failures += testFloatScalb();1695failures += testDoubleScalb();16961697failures += testFloatUlp();1698failures += testDoubleUlp();16991700failures += testFloatSignum();1701failures += testDoubleSignum();17021703if (failures > 0) {1704System.err.println("Testing the recommended functions incurred "1705+ failures + " failures.");1706throw new RuntimeException();1707}1708}1709}171017111712