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