Home | History | Annotate | Download | only in intltest
      1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /********************************************************************
      4  * COPYRIGHT:
      5  * Copyright (c) 1997-2011, International Business Machines Corporation and
      6  * others. All Rights Reserved.
      7  ********************************************************************/
      8 
      9 #include "tsputil.h"
     10 
     11 #include <float.h> // DBL_MAX, DBL_MIN
     12 #include "putilimp.h"
     13 
     14 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break;
     15 
     16 void
     17 PUtilTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
     18 {
     19     //if (exec) logln("TestSuite PUtilTest: ");
     20     switch (index) {
     21         CASE(0, testMaxMin)
     22         CASE(1, testNaN)
     23         CASE(2, testPositiveInfinity)
     24         CASE(3, testNegativeInfinity)
     25         CASE(4, testZero)
     26 //        CASE(, testIEEEremainder)
     27 
     28         default: name = ""; break; //needed to end loop
     29     }
     30 }
     31 
     32 #if 0
     33 void
     34 PUtilTest::testIEEEremainder()
     35 {
     36     double    pinf  = uprv_getInfinity();
     37     double    ninf  = -uprv_getInfinity();
     38     double    nan   = uprv_getNaN();
     39     double    pzero = 0.0;
     40     double    nzero = 0.0;
     41 
     42     nzero *= -1;
     43 
     44     // simple remainder checks
     45     remainderTest(7.0, 2.5, -0.5);
     46     remainderTest(7.0, -2.5, -0.5);
     47 #if U_PLATFORM != U_PF_OS390
     48     // ### TODO:
     49     // The following tests fails on S/390 with IEEE support in release builds;
     50     // debug builds work.
     51     // The functioning of ChoiceFormat is not affected by this bug.
     52     remainderTest(-7.0, 2.5, 0.5);
     53     remainderTest(-7.0, -2.5, 0.5);
     54 #endif
     55     remainderTest(5.0, 3.0, -1.0);
     56 
     57     // this should work
     58     //remainderTest(43.7, 2.5, 1.25);
     59 
     60     /*
     61 
     62     // infinity and real
     63     remainderTest(pinf, 1.0, 1.25);
     64     remainderTest(1.0, pinf, 1.0);
     65     remainderTest(ninf, 1.0, 1.25);
     66     remainderTest(1.0, ninf, 1.0);
     67 
     68     // test infinity and nan
     69     remainderTest(ninf, pinf, 1.25);
     70     remainderTest(ninf, nan, 1.25);
     71     remainderTest(pinf, nan, 1.25);
     72 
     73     // test infinity and zero
     74     remainderTest(pinf, pzero, 1.25);
     75     remainderTest(pinf, nzero, 1.25);
     76     remainderTest(ninf, pzero, 1.25);
     77     remainderTest(ninf, nzero, 1.25);
     78 */
     79 }
     80 
     81 void
     82 PUtilTest::remainderTest(double x, double y, double exp)
     83 {
     84     double result = uprv_IEEEremainder(x,y);
     85 
     86     if(        uprv_isNaN(result) &&
     87         ! ( uprv_isNaN(x) || uprv_isNaN(y))) {
     88         errln(UnicodeString("FAIL: got NaN as result without NaN as argument"));
     89         errln(UnicodeString("      IEEEremainder(") + x + ", " + y + ") is " + result + ", expected " + exp);
     90     }
     91     else if(result != exp)
     92         errln(UnicodeString("FAIL: IEEEremainder(") + x + ", " + y + ") is " + result + ", expected " + exp);
     93     else
     94         logln(UnicodeString("OK: IEEEremainder(") + x + ", " + y + ") is " + result);
     95 
     96 }
     97 #endif
     98 
     99 void
    100 PUtilTest::testMaxMin()
    101 {
    102     double    pinf        = uprv_getInfinity();
    103     double    ninf        = -uprv_getInfinity();
    104     double    nan        = uprv_getNaN();
    105     double    pzero        = 0.0;
    106     double    nzero        = 0.0;
    107 
    108     nzero *= -1;
    109 
    110     // +Inf with -Inf
    111     maxMinTest(pinf, ninf, pinf, TRUE);
    112     maxMinTest(pinf, ninf, ninf, FALSE);
    113 
    114     // +Inf with +0 and -0
    115     maxMinTest(pinf, pzero, pinf, TRUE);
    116     maxMinTest(pinf, pzero, pzero, FALSE);
    117     maxMinTest(pinf, nzero, pinf, TRUE);
    118     maxMinTest(pinf, nzero, nzero, FALSE);
    119 
    120     // -Inf with +0 and -0
    121     maxMinTest(ninf, pzero, pzero, TRUE);
    122     maxMinTest(ninf, pzero, ninf, FALSE);
    123     maxMinTest(ninf, nzero, nzero, TRUE);
    124     maxMinTest(ninf, nzero, ninf, FALSE);
    125 
    126     // NaN with +Inf and -Inf
    127     maxMinTest(pinf, nan, nan, TRUE);
    128     maxMinTest(pinf, nan, nan, FALSE);
    129     maxMinTest(ninf, nan, nan, TRUE);
    130     maxMinTest(ninf, nan, nan, FALSE);
    131 
    132     // NaN with NaN
    133     maxMinTest(nan, nan, nan, TRUE);
    134     maxMinTest(nan, nan, nan, FALSE);
    135 
    136     // NaN with +0 and -0
    137     maxMinTest(nan, pzero, nan, TRUE);
    138     maxMinTest(nan, pzero, nan, FALSE);
    139     maxMinTest(nan, nzero, nan, TRUE);
    140     maxMinTest(nan, nzero, nan, FALSE);
    141 
    142     // +Inf with DBL_MAX and DBL_MIN
    143     maxMinTest(pinf, DBL_MAX, pinf, TRUE);
    144     maxMinTest(pinf, -DBL_MAX, pinf, TRUE);
    145     maxMinTest(pinf, DBL_MIN, pinf, TRUE);
    146     maxMinTest(pinf, -DBL_MIN, pinf, TRUE);
    147     maxMinTest(pinf, DBL_MIN, DBL_MIN, FALSE);
    148     maxMinTest(pinf, -DBL_MIN, -DBL_MIN, FALSE);
    149     maxMinTest(pinf, DBL_MAX, DBL_MAX, FALSE);
    150     maxMinTest(pinf, -DBL_MAX, -DBL_MAX, FALSE);
    151 
    152     // -Inf with DBL_MAX and DBL_MIN
    153     maxMinTest(ninf, DBL_MAX, DBL_MAX, TRUE);
    154     maxMinTest(ninf, -DBL_MAX, -DBL_MAX, TRUE);
    155     maxMinTest(ninf, DBL_MIN, DBL_MIN, TRUE);
    156     maxMinTest(ninf, -DBL_MIN, -DBL_MIN, TRUE);
    157     maxMinTest(ninf, DBL_MIN, ninf, FALSE);
    158     maxMinTest(ninf, -DBL_MIN, ninf, FALSE);
    159     maxMinTest(ninf, DBL_MAX, ninf, FALSE);
    160     maxMinTest(ninf, -DBL_MAX, ninf, FALSE);
    161 
    162     // +0 with DBL_MAX and DBL_MIN
    163     maxMinTest(pzero, DBL_MAX, DBL_MAX, TRUE);
    164     maxMinTest(pzero, -DBL_MAX, pzero, TRUE);
    165     maxMinTest(pzero, DBL_MIN, DBL_MIN, TRUE);
    166     maxMinTest(pzero, -DBL_MIN, pzero, TRUE);
    167     maxMinTest(pzero, DBL_MIN, pzero, FALSE);
    168     maxMinTest(pzero, -DBL_MIN, -DBL_MIN, FALSE);
    169     maxMinTest(pzero, DBL_MAX, pzero, FALSE);
    170     maxMinTest(pzero, -DBL_MAX, -DBL_MAX, FALSE);
    171 
    172     // -0 with DBL_MAX and DBL_MIN
    173     maxMinTest(nzero, DBL_MAX, DBL_MAX, TRUE);
    174     maxMinTest(nzero, -DBL_MAX, nzero, TRUE);
    175     maxMinTest(nzero, DBL_MIN, DBL_MIN, TRUE);
    176     maxMinTest(nzero, -DBL_MIN, nzero, TRUE);
    177     maxMinTest(nzero, DBL_MIN, nzero, FALSE);
    178     maxMinTest(nzero, -DBL_MIN, -DBL_MIN, FALSE);
    179     maxMinTest(nzero, DBL_MAX, nzero, FALSE);
    180     maxMinTest(nzero, -DBL_MAX, -DBL_MAX, FALSE);
    181 }
    182 
    183 void
    184 PUtilTest::maxMinTest(double a, double b, double exp, UBool max)
    185 {
    186     double result = 0.0;
    187 
    188     if(max)
    189         result = uprv_fmax(a, b);
    190     else
    191         result = uprv_fmin(a, b);
    192 
    193     UBool nanResultOK = (uprv_isNaN(a) || uprv_isNaN(b));
    194 
    195     if(uprv_isNaN(result) && ! nanResultOK) {
    196         errln(UnicodeString("FAIL: got NaN as result without NaN as argument"));
    197         if(max)
    198             errln(UnicodeString("      max(") + a + ", " + b + ") is " + result + ", expected " + exp);
    199         else
    200             errln(UnicodeString("      min(") + a + ", " + b + ") is " + result + ", expected " + exp);
    201     }
    202     else if(result != exp && ! (uprv_isNaN(result) || uprv_isNaN(exp)))
    203         if(max)
    204             errln(UnicodeString("FAIL: max(") + a + ", " + b + ") is " + result + ", expected " + exp);
    205         else
    206             errln(UnicodeString("FAIL: min(") + a + ", " + b + ") is " + result + ", expected " + exp);
    207     else {
    208         if (verbose) {
    209             if(max)
    210                 logln(UnicodeString("OK: max(") + a + ", " + b + ") is " + result);
    211             else
    212                 logln(UnicodeString("OK: min(") + a + ", " + b + ") is " + result);
    213         }
    214     }
    215 }
    216 //==============================
    217 
    218 // NaN is weird- comparisons with NaN _always_ return false, with the
    219 // exception of !=, which _always_ returns true
    220 void
    221 PUtilTest::testNaN(void)
    222 {
    223     logln("NaN tests may show that the expected NaN!=NaN etc. is not true on some");
    224     logln("platforms; however, ICU does not rely on them because it defines");
    225     logln("and uses uprv_isNaN(). Therefore, most failing NaN tests only report warnings.");
    226 
    227     PUtilTest::testIsNaN();
    228     PUtilTest::NaNGT();
    229     PUtilTest::NaNLT();
    230     PUtilTest::NaNGTE();
    231     PUtilTest::NaNLTE();
    232     PUtilTest::NaNE();
    233     PUtilTest::NaNNE();
    234 
    235     logln("End of NaN tests.");
    236 }
    237 
    238 //==============================
    239 
    240 void
    241 PUtilTest::testPositiveInfinity(void)
    242 {
    243     double  pinf    = uprv_getInfinity();
    244     double  ninf    = -uprv_getInfinity();
    245     double  ten     = 10.0;
    246 
    247     if(uprv_isInfinite(pinf) != TRUE) {
    248         errln("FAIL: isInfinite(+Infinity) returned FALSE, should be TRUE.");
    249     }
    250 
    251     if(uprv_isPositiveInfinity(pinf) != TRUE) {
    252         errln("FAIL: isPositiveInfinity(+Infinity) returned FALSE, should be TRUE.");
    253     }
    254 
    255     if(uprv_isNegativeInfinity(pinf) != FALSE) {
    256         errln("FAIL: isNegativeInfinity(+Infinity) returned TRUE, should be FALSE.");
    257     }
    258 
    259     if((pinf > DBL_MAX) != TRUE) {
    260         errln("FAIL: +Infinity > DBL_MAX returned FALSE, should be TRUE.");
    261     }
    262 
    263     if((pinf > DBL_MIN) != TRUE) {
    264         errln("FAIL: +Infinity > DBL_MIN returned FALSE, should be TRUE.");
    265     }
    266 
    267     if((pinf > ninf) != TRUE) {
    268         errln("FAIL: +Infinity > -Infinity returned FALSE, should be TRUE.");
    269     }
    270 
    271     if((pinf > ten) != TRUE) {
    272         errln("FAIL: +Infinity > 10.0 returned FALSE, should be TRUE.");
    273     }
    274 }
    275 
    276 //==============================
    277 
    278 void
    279 PUtilTest::testNegativeInfinity(void)
    280 {
    281     double  pinf    = uprv_getInfinity();
    282     double  ninf    = -uprv_getInfinity();
    283     double  ten     = 10.0;
    284 
    285     if(uprv_isInfinite(ninf) != TRUE) {
    286         errln("FAIL: isInfinite(-Infinity) returned FALSE, should be TRUE.");
    287     }
    288 
    289     if(uprv_isNegativeInfinity(ninf) != TRUE) {
    290         errln("FAIL: isNegativeInfinity(-Infinity) returned FALSE, should be TRUE.");
    291     }
    292 
    293     if(uprv_isPositiveInfinity(ninf) != FALSE) {
    294         errln("FAIL: isPositiveInfinity(-Infinity) returned TRUE, should be FALSE.");
    295     }
    296 
    297     if((ninf < DBL_MAX) != TRUE) {
    298         errln("FAIL: -Infinity < DBL_MAX returned FALSE, should be TRUE.");
    299     }
    300 
    301     if((ninf < DBL_MIN) != TRUE) {
    302         errln("FAIL: -Infinity < DBL_MIN returned FALSE, should be TRUE.");
    303     }
    304 
    305     if((ninf < pinf) != TRUE) {
    306         errln("FAIL: -Infinity < +Infinity returned FALSE, should be TRUE.");
    307     }
    308 
    309     if((ninf < ten) != TRUE) {
    310         errln("FAIL: -Infinity < 10.0 returned FALSE, should be TRUE.");
    311     }
    312 }
    313 
    314 //==============================
    315 
    316 // notes about zero:
    317 // -0.0 == 0.0 == TRUE
    318 // -0.0 <  0.0 == FALSE
    319 // generating -0.0 must be done at runtime.  compiler apparently ignores sign?
    320 void
    321 PUtilTest::testZero(void)
    322 {
    323     // volatile is used to fake out the compiler optimizer.  We really want to divide by 0.
    324     volatile double pzero   = 0.0;
    325     volatile double nzero   = 0.0;
    326 
    327     nzero *= -1;
    328 
    329     if((pzero == nzero) != TRUE) {
    330         errln("FAIL: 0.0 == -0.0 returned FALSE, should be TRUE.");
    331     }
    332 
    333     if((pzero > nzero) != FALSE) {
    334         errln("FAIL: 0.0 > -0.0 returned TRUE, should be FALSE.");
    335     }
    336 
    337     if((pzero >= nzero) != TRUE) {
    338         errln("FAIL: 0.0 >= -0.0 returned FALSE, should be TRUE.");
    339     }
    340 
    341     if((pzero < nzero) != FALSE) {
    342         errln("FAIL: 0.0 < -0.0 returned TRUE, should be FALSE.");
    343     }
    344 
    345     if((pzero <= nzero) != TRUE) {
    346         errln("FAIL: 0.0 <= -0.0 returned FALSE, should be TRUE.");
    347     }
    348 #if U_PLATFORM != U_PF_OS400 /* OS/400 will generate divide by zero exception MCH1214 */
    349     if(uprv_isInfinite(1/pzero) != TRUE) {
    350         errln("FAIL: isInfinite(1/0.0) returned FALSE, should be TRUE.");
    351     }
    352 
    353     if(uprv_isInfinite(1/nzero) != TRUE) {
    354         errln("FAIL: isInfinite(1/-0.0) returned FALSE, should be TRUE.");
    355     }
    356 
    357     if(uprv_isPositiveInfinity(1/pzero) != TRUE) {
    358         errln("FAIL: isPositiveInfinity(1/0.0) returned FALSE, should be TRUE.");
    359     }
    360 
    361     if(uprv_isNegativeInfinity(1/nzero) != TRUE) {
    362         errln("FAIL: isNegativeInfinity(1/-0.0) returned FALSE, should be TRUE.");
    363     }
    364 #endif
    365 }
    366 
    367 //==============================
    368 
    369 void
    370 PUtilTest::testIsNaN(void)
    371 {
    372     double  pinf    = uprv_getInfinity();
    373     double  ninf    = -uprv_getInfinity();
    374     double  nan     = uprv_getNaN();
    375     double  ten     = 10.0;
    376 
    377     if(uprv_isNaN(nan) == FALSE) {
    378         errln("FAIL: isNaN() returned FALSE for NaN.");
    379     }
    380 
    381     if(uprv_isNaN(pinf) == TRUE) {
    382         errln("FAIL: isNaN() returned TRUE for +Infinity.");
    383     }
    384 
    385     if(uprv_isNaN(ninf) == TRUE) {
    386         errln("FAIL: isNaN() returned TRUE for -Infinity.");
    387     }
    388 
    389     if(uprv_isNaN(ten) == TRUE) {
    390         errln("FAIL: isNaN() returned TRUE for 10.0.");
    391     }
    392 }
    393 
    394 //==============================
    395 
    396 void
    397 PUtilTest::NaNGT(void)
    398 {
    399     double  pinf    = uprv_getInfinity();
    400     double  ninf    = -uprv_getInfinity();
    401     double  nan     = uprv_getNaN();
    402     double  ten     = 10.0;
    403 
    404     if((nan > nan) != FALSE) {
    405         logln("WARNING: NaN > NaN returned TRUE, should be FALSE");
    406     }
    407 
    408     if((nan > pinf) != FALSE) {
    409         logln("WARNING: NaN > +Infinity returned TRUE, should be FALSE");
    410     }
    411 
    412     if((nan > ninf) != FALSE) {
    413         logln("WARNING: NaN > -Infinity returned TRUE, should be FALSE");
    414     }
    415 
    416     if((nan > ten) != FALSE) {
    417         logln("WARNING: NaN > 10.0 returned TRUE, should be FALSE");
    418     }
    419 }
    420 
    421 //==============================
    422 
    423 void
    424 PUtilTest::NaNLT(void)
    425 {
    426     double  pinf    = uprv_getInfinity();
    427     double  ninf    = -uprv_getInfinity();
    428     double  nan     = uprv_getNaN();
    429     double  ten     = 10.0;
    430 
    431     if((nan < nan) != FALSE) {
    432         logln("WARNING: NaN < NaN returned TRUE, should be FALSE");
    433     }
    434 
    435     if((nan < pinf) != FALSE) {
    436         logln("WARNING: NaN < +Infinity returned TRUE, should be FALSE");
    437     }
    438 
    439     if((nan < ninf) != FALSE) {
    440         logln("WARNING: NaN < -Infinity returned TRUE, should be FALSE");
    441     }
    442 
    443     if((nan < ten) != FALSE) {
    444         logln("WARNING: NaN < 10.0 returned TRUE, should be FALSE");
    445     }
    446 }
    447 
    448 //==============================
    449 
    450 void
    451 PUtilTest::NaNGTE(void)
    452 {
    453     double  pinf    = uprv_getInfinity();
    454     double  ninf    = -uprv_getInfinity();
    455     double  nan     = uprv_getNaN();
    456     double  ten     = 10.0;
    457 
    458     if((nan >= nan) != FALSE) {
    459         logln("WARNING: NaN >= NaN returned TRUE, should be FALSE");
    460     }
    461 
    462     if((nan >= pinf) != FALSE) {
    463         logln("WARNING: NaN >= +Infinity returned TRUE, should be FALSE");
    464     }
    465 
    466     if((nan >= ninf) != FALSE) {
    467         logln("WARNING: NaN >= -Infinity returned TRUE, should be FALSE");
    468     }
    469 
    470     if((nan >= ten) != FALSE) {
    471         logln("WARNING: NaN >= 10.0 returned TRUE, should be FALSE");
    472     }
    473 }
    474 
    475 //==============================
    476 
    477 void
    478 PUtilTest::NaNLTE(void)
    479 {
    480     double  pinf    = uprv_getInfinity();
    481     double  ninf    = -uprv_getInfinity();
    482     double  nan     = uprv_getNaN();
    483     double  ten     = 10.0;
    484 
    485     if((nan <= nan) != FALSE) {
    486         logln("WARNING: NaN <= NaN returned TRUE, should be FALSE");
    487     }
    488 
    489     if((nan <= pinf) != FALSE) {
    490         logln("WARNING: NaN <= +Infinity returned TRUE, should be FALSE");
    491     }
    492 
    493     if((nan <= ninf) != FALSE) {
    494         logln("WARNING: NaN <= -Infinity returned TRUE, should be FALSE");
    495     }
    496 
    497     if((nan <= ten) != FALSE) {
    498         logln("WARNING: NaN <= 10.0 returned TRUE, should be FALSE");
    499     }
    500 }
    501 
    502 //==============================
    503 
    504 void
    505 PUtilTest::NaNE(void)
    506 {
    507     double  pinf    = uprv_getInfinity();
    508     double  ninf    = -uprv_getInfinity();
    509     double  nan     = uprv_getNaN();
    510     double  ten     = 10.0;
    511 
    512     if((nan == nan) != FALSE) {
    513         logln("WARNING: NaN == NaN returned TRUE, should be FALSE");
    514     }
    515 
    516     if((nan == pinf) != FALSE) {
    517         logln("WARNING: NaN == +Infinity returned TRUE, should be FALSE");
    518     }
    519 
    520     if((nan == ninf) != FALSE) {
    521         logln("WARNING: NaN == -Infinity returned TRUE, should be FALSE");
    522     }
    523 
    524     if((nan == ten) != FALSE) {
    525         logln("WARNING: NaN == 10.0 returned TRUE, should be FALSE");
    526     }
    527 }
    528 
    529 //==============================
    530 
    531 void
    532 PUtilTest::NaNNE(void)
    533 {
    534     double  pinf    = uprv_getInfinity();
    535     double  ninf    = -uprv_getInfinity();
    536     double  nan     = uprv_getNaN();
    537     double  ten     = 10.0;
    538 
    539     if((nan != nan) != TRUE) {
    540         logln("WARNING: NaN != NaN returned FALSE, should be TRUE");
    541     }
    542 
    543     if((nan != pinf) != TRUE) {
    544         logln("WARNING: NaN != +Infinity returned FALSE, should be TRUE");
    545     }
    546 
    547     if((nan != ninf) != TRUE) {
    548         logln("WARNING: NaN != -Infinity returned FALSE, should be TRUE");
    549     }
    550 
    551     if((nan != ten) != TRUE) {
    552         logln("WARNING: NaN != 10.0 returned FALSE, should be TRUE");
    553     }
    554 }
    555