• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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
testMaxMin()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
maxMinTest(double a,double b,double exp,UBool max)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
testNaN(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
testPositiveInfinity(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
testNegativeInfinity(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
testZero(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
testIsNaN(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
NaNGT(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
NaNLT(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
NaNGTE(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
NaNLTE(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
NaNE(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
NaNNE(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 
inlineTriple(int32_t x)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
testU_INLINE()561 PUtilTest::testU_INLINE() {
562     if(inlineTriple(2)!=6 || inlineTriple(-55)!=-165) {
563         errln("inlineTriple() failed");
564     }
565 }
566