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