]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/ieeetest/ieeetest.cpp
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / test / ieeetest / ieeetest.cpp
1 /*******************************************************************************
2 *
3 * Copyright (C) 1998-2001, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 *
6 *******************************************************************************
7 * File ieeetest.cpp
8 *
9 * Modification History:
10 *
11 * Date Name Description
12 * 08/21/98 stephen Creation.
13 *******************************************************************************
14 */
15
16 #include <stdio.h>
17 #include <float.h> // DBL_MAX
18
19 #include "ieeetest.h"
20 #include "unicode/utypes.h"
21 #include "unicode/putil.h"
22
23 //==============================
24
25 int
26 main(int argc,
27 char **argv)
28 {
29 int flags = IEEETest::kNone;
30
31 // parse command line switches
32 for(int i = 1; i < argc; ++i) {
33 if(argv[i][0] == '-') {
34 switch(argv[i][1]) {
35 case 'v':
36 flags += IEEETest::kVerboseMode;
37 break;
38
39 case '?':
40 case 'h':
41 case 'H':
42 usage(argv[0]);
43 return 0;
44
45 default:
46 break;
47 }
48 }
49 }
50
51 IEEETest test(flags);
52
53 return test.run();
54 }
55
56 //==============================
57
58 void
59 usage(const char *execName)
60 {
61 fprintf(stdout, "usage: %s [flags]\n\n"
62 "Flags:\n"
63 "-v Verbose mode\n", execName);
64 }
65
66 //==============================
67
68 IEEETest::IEEETest(int flags)
69 : mFlags(flags),
70 mTestLevel(0),
71 mNeedLogIndent(TRUE),
72 mNeedErrIndent(TRUE)
73 {}
74
75 //==============================
76
77 IEEETest::~IEEETest()
78 {}
79
80 //==============================
81
82 int
83 IEEETest::run(void)
84 {
85 int errCount = 0;
86
87 logln();
88 log("Starting IEEETest").logln();
89 increaseTestLevel();
90
91 // add more tests here
92 errCount += runTest("NaN behavior", &IEEETest::testNaN);
93 errCount += runTest("+Infinity behavior", &IEEETest::testPositiveInfinity);
94 errCount += runTest("-Infinity behavior", &IEEETest::testNegativeInfinity);
95 errCount += runTest("Zero behavior", &IEEETest::testZero);
96
97 decreaseTestLevel();
98 if(errCount == 0)
99 log("IEEETest Passed");
100 else {
101 log("IEEETest failed with ").log(errCount)
102 .log(errCount == 1 ? " error." : " errors.");
103 }
104 logln();
105
106 if(errCount == 0 && ! (mFlags & kVerboseMode))
107 fprintf(stdout, "\nAll tests passed without error.\n");
108
109 return errCount;
110 }
111
112 //==============================
113 int
114 IEEETest::runTest(const char *testName,
115 int (IEEETest::*testFunc)(void))
116 {
117 logln().log("Running test ").log(testName).logln();
118 increaseTestLevel();
119 int errCount = (this->*testFunc)();
120 decreaseTestLevel();
121 log("Test ").log(testName);
122 if(errCount == 0)
123 log(" passed.");
124 else {
125 log(" failed with ").log(errCount)
126 .log(errCount == 1 ? " error." : " errors.");
127 }
128
129 logln().logln();
130
131 return errCount;
132 }
133
134
135 //==============================
136
137 // NaN is weird- comparisons with NaN _always_ return false, with the
138 // exception of !=, which _always_ returns true
139 int
140 IEEETest::testNaN(void)
141 {
142 int errCount = 0;
143
144 log("NaN tests may show that the expected NaN!=NaN etc. is not true on some").logln();
145 log("platforms; however, ICU does not rely on them because it defines").logln();
146 log("and uses uprv_isNaN(). Therefore, most failing NaN tests only report warnings.").logln();
147
148 errCount += runTest("isNaN", &IEEETest::testIsNaN);
149 errCount += runTest("NaN >", &IEEETest::NaNGT);
150 errCount += runTest("NaN <", &IEEETest::NaNLT);
151 errCount += runTest("NaN >=", &IEEETest::NaNGTE);
152 errCount += runTest("NaN <=", &IEEETest::NaNLTE);
153 errCount += runTest("NaN ==", &IEEETest::NaNE);
154 errCount += runTest("NaN !=", &IEEETest::NaNNE);
155
156 log("End of NaN tests.").logln();
157
158 return errCount;
159 }
160
161 //==============================
162
163 int
164 IEEETest::testPositiveInfinity(void)
165 {
166 int errCount = 0;
167 double pinf = uprv_getInfinity();
168 double ninf = -uprv_getInfinity();
169 double ten = 10.0;
170
171 if(uprv_isInfinite(pinf) != TRUE) {
172 err("FAIL: isInfinite(+Infinity) returned FALSE, should be TRUE.").errln();
173 errCount++;
174 }
175
176 if(uprv_isPositiveInfinity(pinf) != TRUE) {
177 err("FAIL: isPositiveInfinity(+Infinity) returned FALSE, should be TRUE.").errln();
178 errCount++;
179 }
180
181 if(uprv_isNegativeInfinity(pinf) != FALSE) {
182 err("FAIL: isNegativeInfinity(+Infinity) returned TRUE, should be FALSE.").errln();
183 errCount++;
184 }
185
186 if(pinf > DBL_MAX != TRUE) {
187 err("FAIL: +Infinity > DBL_MAX returned FALSE, should be TRUE.").errln();
188 errCount++;
189 }
190
191 if(pinf > DBL_MIN != TRUE) {
192 err("FAIL: +Infinity > DBL_MIN returned FALSE, should be TRUE.").errln();
193 errCount++;
194 }
195
196 if(pinf > ninf != TRUE) {
197 err("FAIL: +Infinity > -Infinity returned FALSE, should be TRUE.").errln();
198 errCount++;
199 }
200
201 if(pinf > ten != TRUE) {
202 err("FAIL: +Infinity > 10.0 returned FALSE, should be TRUE.").errln();
203 errCount++;
204 }
205
206 return errCount;
207 }
208
209 //==============================
210
211 int
212 IEEETest::testNegativeInfinity(void)
213 {
214 int errCount = 0;
215 double pinf = uprv_getInfinity();
216 double ninf = -uprv_getInfinity();
217 double ten = 10.0;
218
219 if(uprv_isInfinite(ninf) != TRUE) {
220 err("FAIL: isInfinite(-Infinity) returned FALSE, should be TRUE.").errln();
221 errCount++;
222 }
223
224 if(uprv_isNegativeInfinity(ninf) != TRUE) {
225 err("FAIL: isNegativeInfinity(-Infinity) returned FALSE, should be TRUE.").errln();
226 errCount++;
227 }
228
229 if(uprv_isPositiveInfinity(ninf) != FALSE) {
230 err("FAIL: isPositiveInfinity(-Infinity) returned TRUE, should be FALSE.").errln();
231 errCount++;
232 }
233
234 if(ninf < DBL_MAX != TRUE) {
235 err("FAIL: -Infinity < DBL_MAX returned FALSE, should be TRUE.").errln();
236 errCount++;
237 }
238
239 if(ninf < DBL_MIN != TRUE) {
240 err("FAIL: -Infinity < DBL_MIN returned FALSE, should be TRUE.").errln();
241 errCount++;
242 }
243
244 if(ninf < pinf != TRUE) {
245 err("FAIL: -Infinity < +Infinity returned FALSE, should be TRUE.").errln();
246 errCount++;
247 }
248
249 if(ninf < ten != TRUE) {
250 err("FAIL: -Infinity < 10.0 returned FALSE, should be TRUE.").errln();
251 errCount++;
252 }
253
254 return errCount;
255 }
256
257 //==============================
258
259 // notes about zero:
260 // -0.0 == 0.0 == TRUE
261 // -0.0 < 0.0 == FALSE
262 // generating -0.0 must be done at runtime. compiler apparently ignores sign?
263 int
264 IEEETest::testZero(void)
265 {
266 int errCount = 0;
267 // volatile is used to fake out the compiler optimizer. We really want to divide by 0.
268 volatile double pzero = 0.0;
269 volatile double nzero = 0.0;
270
271 nzero *= -1;
272
273 if(pzero == nzero != TRUE) {
274 err("FAIL: 0.0 == -0.0 returned FALSE, should be TRUE.").errln();
275 errCount++;
276 }
277
278 if(pzero > nzero != FALSE) {
279 err("FAIL: 0.0 > -0.0 returned TRUE, should be FALSE.").errln();
280 errCount++;
281 }
282
283 if(pzero >= nzero != TRUE) {
284 err("FAIL: 0.0 >= -0.0 returned FALSE, should be TRUE.").errln();
285 errCount++;
286 }
287
288 if(pzero < nzero != FALSE) {
289 err("FAIL: 0.0 < -0.0 returned TRUE, should be FALSE.").errln();
290 errCount++;
291 }
292
293 if(pzero <= nzero != TRUE) {
294 err("FAIL: 0.0 <= -0.0 returned FALSE, should be TRUE.").errln();
295 errCount++;
296 }
297
298 if(uprv_isInfinite(1/pzero) != TRUE) {
299 err("FAIL: isInfinite(1/0.0) returned FALSE, should be TRUE.").errln();
300 errCount++;
301 }
302
303 if(uprv_isInfinite(1/nzero) != TRUE) {
304 err("FAIL: isInfinite(1/-0.0) returned FALSE, should be TRUE.").errln();
305 errCount++;
306 }
307
308 if(uprv_isPositiveInfinity(1/pzero) != TRUE) {
309 err("FAIL: isPositiveInfinity(1/0.0) returned FALSE, should be TRUE.").errln();
310 errCount++;
311 }
312
313 if(uprv_isNegativeInfinity(1/nzero) != TRUE) {
314 err("FAIL: isNegativeInfinity(1/-0.0) returned FALSE, should be TRUE.").errln();
315 errCount++;
316 }
317
318 return errCount;
319 }
320
321 //==============================
322
323 int
324 IEEETest::testIsNaN(void)
325 {
326 int numErrors = 0;
327 double pinf = uprv_getInfinity();
328 double ninf = -uprv_getInfinity();
329 double nan = uprv_getNaN();
330 double ten = 10.0;
331
332 if(uprv_isNaN(nan) == FALSE) {
333 err("FAIL: isNaN() returned FALSE for NaN.").errln();
334 numErrors++;
335 }
336
337 if(uprv_isNaN(pinf) == TRUE) {
338 err("FAIL: isNaN() returned TRUE for +Infinity.").errln();
339 numErrors++;
340 }
341
342 if(uprv_isNaN(ninf) == TRUE) {
343 err("FAIL: isNaN() returned TRUE for -Infinity.").errln();
344 numErrors++;
345 }
346
347 if(uprv_isNaN(ten) == TRUE) {
348 err("FAIL: isNaN() returned TRUE for 10.0.").errln();
349 numErrors++;
350 }
351
352 return numErrors;
353 }
354
355 //==============================
356
357 int
358 IEEETest::NaNGT(void)
359 {
360 double pinf = uprv_getInfinity();
361 double ninf = -uprv_getInfinity();
362 double nan = uprv_getNaN();
363 double ten = 10.0;
364 int numErrors = 0;
365
366 if(nan > nan != FALSE) {
367 log("WARNING: NaN > NaN returned TRUE, should be FALSE").logln();
368 }
369
370 if(nan > pinf != FALSE) {
371 log("WARNING: NaN > +Infinity returned TRUE, should be FALSE").logln();
372 }
373
374 if(nan > ninf != FALSE) {
375 log("WARNING: NaN > -Infinity returned TRUE, should be FALSE").logln();
376 }
377
378 if(nan > ten != FALSE) {
379 log("WARNING: NaN > 10.0 returned TRUE, should be FALSE").logln();
380 }
381
382 return numErrors;
383 }
384
385 //==============================
386
387 int
388 IEEETest::NaNLT(void)
389 {
390 double pinf = uprv_getInfinity();
391 double ninf = -uprv_getInfinity();
392 double nan = uprv_getNaN();
393 double ten = 10.0;
394 int numErrors = 0;
395
396 if(nan < nan != FALSE) {
397 log("WARNING: NaN < NaN returned TRUE, should be FALSE").logln();
398 }
399
400 if(nan < pinf != FALSE) {
401 log("WARNING: NaN < +Infinity returned TRUE, should be FALSE").logln();
402 }
403
404 if(nan < ninf != FALSE) {
405 log("WARNING: NaN < -Infinity returned TRUE, should be FALSE").logln();
406 }
407
408 if(nan < ten != FALSE) {
409 log("WARNING: NaN < 10.0 returned TRUE, should be FALSE").logln();
410 }
411
412 return numErrors;
413 }
414
415 //==============================
416
417 int
418 IEEETest::NaNGTE(void)
419 {
420 double pinf = uprv_getInfinity();
421 double ninf = -uprv_getInfinity();
422 double nan = uprv_getNaN();
423 double ten = 10.0;
424 int numErrors = 0;
425
426 if(nan >= nan != FALSE) {
427 log("WARNING: NaN >= NaN returned TRUE, should be FALSE").logln();
428 }
429
430 if(nan >= pinf != FALSE) {
431 log("WARNING: NaN >= +Infinity returned TRUE, should be FALSE").logln();
432 }
433
434 if(nan >= ninf != FALSE) {
435 log("WARNING: NaN >= -Infinity returned TRUE, should be FALSE").logln();
436 }
437
438 if(nan >= ten != FALSE) {
439 log("WARNING: NaN >= 10.0 returned TRUE, should be FALSE").logln();
440 }
441
442 return numErrors;
443 }
444
445 //==============================
446
447 int
448 IEEETest::NaNLTE(void)
449 {
450 double pinf = uprv_getInfinity();
451 double ninf = -uprv_getInfinity();
452 double nan = uprv_getNaN();
453 double ten = 10.0;
454 int numErrors = 0;
455
456 if(nan <= nan != FALSE) {
457 log("WARNING: NaN <= NaN returned TRUE, should be FALSE").logln();
458 }
459
460 if(nan <= pinf != FALSE) {
461 log("WARNING: NaN <= +Infinity returned TRUE, should be FALSE").logln();
462 }
463
464 if(nan <= ninf != FALSE) {
465 log("WARNING: NaN <= -Infinity returned TRUE, should be FALSE").logln();
466 }
467
468 if(nan <= ten != FALSE) {
469 log("WARNING: NaN <= 10.0 returned TRUE, should be FALSE").logln();
470 }
471
472 return numErrors;
473 }
474
475 //==============================
476
477 int
478 IEEETest::NaNE(void)
479 {
480 double pinf = uprv_getInfinity();
481 double ninf = -uprv_getInfinity();
482 double nan = uprv_getNaN();
483 double ten = 10.0;
484 int numErrors = 0;
485
486 if(nan == nan != FALSE) {
487 log("WARNING: NaN == NaN returned TRUE, should be FALSE").logln();
488 }
489
490 if(nan == pinf != FALSE) {
491 log("WARNING: NaN == +Infinity returned TRUE, should be FALSE").logln();
492 }
493
494 if(nan == ninf != FALSE) {
495 log("WARNING: NaN == -Infinity returned TRUE, should be FALSE").logln();
496 }
497
498 if(nan == ten != FALSE) {
499 log("WARNING: NaN == 10.0 returned TRUE, should be FALSE").logln();
500 }
501
502 return numErrors;
503 }
504
505 //==============================
506
507 int
508 IEEETest::NaNNE(void)
509 {
510 double pinf = uprv_getInfinity();
511 double ninf = -uprv_getInfinity();
512 double nan = uprv_getNaN();
513 double ten = 10.0;
514 int numErrors = 0;
515
516 if(nan != nan != TRUE) {
517 log("WARNING: NaN != NaN returned FALSE, should be TRUE").logln();
518 }
519
520 if(nan != pinf != TRUE) {
521 log("WARNING: NaN != +Infinity returned FALSE, should be TRUE").logln();
522 }
523
524 if(nan != ninf != TRUE) {
525 log("WARNING: NaN != -Infinity returned FALSE, should be TRUE").logln();
526 }
527
528 if(nan != ten != TRUE) {
529 log("WARNING: NaN != 10.0 returned FALSE, should be TRUE").logln();
530 }
531
532 return numErrors;
533 }
534
535 //==============================
536
537 IEEETest&
538 IEEETest::log(char c)
539 {
540 if(mFlags & kVerboseMode) {
541 if(mNeedLogIndent) {
542 for(int j = 0; j < 2 * getTestLevel(); ++j)
543 fputc(' ', stdout);
544 mNeedLogIndent = FALSE;
545 }
546 fputc(c, stdout);
547 }
548 return *this;
549 }
550
551 //==============================
552
553 IEEETest&
554 IEEETest::log(const char *s)
555 {
556 if(mFlags & kVerboseMode) {
557 if(mNeedLogIndent) {
558 for(int j = 0; j < 2 * getTestLevel(); ++j)
559 fputc(' ', stdout);
560 mNeedLogIndent = FALSE;
561 }
562 fprintf(stdout, "%s", s);
563 }
564 return *this;
565 }
566
567 //==============================
568
569 IEEETest&
570 IEEETest::log(int i)
571 {
572 if(mFlags & kVerboseMode) {
573 if(mNeedLogIndent) {
574 for(int j = 0; j < 2 * getTestLevel(); ++j)
575 fputc(' ', stdout);
576 mNeedLogIndent = FALSE;
577 }
578 fprintf(stdout, "%d", i);
579 }
580 return *this;
581 }
582
583 //==============================
584
585 IEEETest&
586 IEEETest::log(long l)
587 {
588 if(mFlags & kVerboseMode) {
589 if(mNeedLogIndent) {
590 for(int j = 0; j < 2 * getTestLevel(); ++j)
591 fputc(' ', stdout);
592 mNeedLogIndent = FALSE;
593 }
594 fprintf(stdout, "%ld", l);
595 }
596 return *this;
597 }
598
599 //==============================
600
601 IEEETest&
602 IEEETest::log(double d)
603 {
604 if(mFlags & kVerboseMode) {
605 if(mNeedLogIndent) {
606 for(int j = 0; j < 2 * getTestLevel(); ++j)
607 fputc(' ', stdout);
608 mNeedLogIndent = FALSE;
609 }
610 fprintf(stdout, "%g", d);
611 }
612 return *this;
613 }
614
615 //==============================
616
617 IEEETest&
618 IEEETest::logln(void)
619 {
620 if(mFlags & kVerboseMode)
621 fputc('\n', stdout);
622 mNeedLogIndent = TRUE;
623 return *this;
624 }
625
626 //==============================
627
628 IEEETest&
629 IEEETest::err(char c)
630 {
631 if(mNeedErrIndent) {
632 for(int j = 0; j < 2 * getTestLevel(); ++j)
633 fputc(' ', stderr);
634 mNeedErrIndent = FALSE;
635 }
636 fputc(c, stderr);
637 return *this;
638 }
639
640 //==============================
641
642 IEEETest&
643 IEEETest::err(const char *s)
644 {
645 if(mNeedErrIndent) {
646 for(int j = 0; j < 2 * getTestLevel(); ++j)
647 fputc(' ', stderr);
648 mNeedErrIndent = FALSE;
649 }
650 fprintf(stderr, "%s", s);
651 return *this;
652 }
653
654 //==============================
655
656 IEEETest&
657 IEEETest::err(int i)
658 {
659 if(mNeedErrIndent) {
660 for(int j = 0; j < 2 * getTestLevel(); ++j)
661 fputc(' ', stderr);
662 mNeedErrIndent = FALSE;
663 }
664 fprintf(stderr, "%d", i);
665 return *this;
666 }
667
668 //==============================
669
670 IEEETest&
671 IEEETest::err(long l)
672 {
673 if(mNeedErrIndent) {
674 for(int j = 0; j < 2 * getTestLevel(); ++j)
675 fputc(' ', stderr);
676 mNeedErrIndent = FALSE;
677 }
678 fprintf(stderr, "%ld", l);
679 return *this;
680 }
681
682 //==============================
683
684 IEEETest&
685 IEEETest::err(double d)
686 {
687 if(mNeedErrIndent) {
688 for(int j = 0; j < 2 * getTestLevel(); ++j)
689 fputc(' ', stderr);
690 mNeedErrIndent = FALSE;
691 }
692 fprintf(stderr, "%g", d);
693 return *this;
694 }
695
696 //==============================
697
698 IEEETest&
699 IEEETest::errln(void)
700 {
701 fputc('\n', stderr);
702 mNeedErrIndent = TRUE;
703 return *this;
704 }
705
706 //eof