1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2010, 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