1 /* testfloatnum.c: regression test for floatnum. */
2 /*
3     Copyright (C) 2007, 2008 Wolf Lammen.
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License , or
8     (at your option) any later version.
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program; see the file COPYING.  If not, write to:
16 
17       The Free Software Foundation, Inc.
18       59 Temple Place, Suite 330
19       Boston, MA 02111-1307 USA.
20 
21 
22     You may contact the author by:
23        e-mail:  ookami1 <at> gmx <dot> de
24        mail:  Wolf Lammen
25               Oertzweg 45
26               22307 Hamburg
27               Germany
28 
29 *************************************************************************/
30 
31 /*======================================================================
32 
33                              REGRESSION TESTS
34 
35 =======================================================================*/
36 
37 /* a few tests depend on 32 bit integer size, fix this in future!! */
38 
39 #include "math/floatconst.h"
40 #include "math/floatcommon.h"
41 #include "math/floatlog.h"
42 #include "math/floatexp.h"
43 #include "math/floattrig.h"
44 #include "math/floathmath.h"
45 #include "math/floatipower.h"
46 #include "math/floatpower.h"
47 #include "math/floatgamma.h"
48 #include "math/floatlogic.h"
49 #include "math/floaterf.h"
50 #include <stdio.h>
51 #include <string.h>
52 
53 #ifdef _FLOATNUMTEST
54 
55 /* From math/floaterf.c */
56 char erfseries(floatnum x, int digits);
57 char erfcsum(floatnum x, int digits);
58 char erfcasymptotic(floatnum x, int digits);
59 /* From math/floatgamma.c */
60 char binetasymptotic(floatnum x, int digits);
61 
62 #define msbu (1u << (sizeof(unsigned)*8-1))
63 #define maxu (msbu + (msbu-1))
64 #define msbi (1 << (sizeof(int)*8-2))
65 #define maxi (msbi + (msbi -1))
66 #define mini (-maxi - 1)
67 
68 static int g_total_tests = 0;
69 static int g_failed_tests = 0;
70 static int g_new_failed_tests = 0;
71 
72 #define tc_out(value, digits, base, mode, result) \
73   _tc_out(__FILE__,__LINE__, #value"/"#digits"/"#base"/"#mode, \
74           value, digits, base, mode, result)
75 
76 #define tc_in(expr, result) \
77   _tc_in(__FILE__,__LINE__, #expr, expr, result)
78 
DisplayErrorOnStrMismatch(const char * file,int line,const char * msg,const char * result,const char * expected,int * failed,int * newFailed,int issue)79 void DisplayErrorOnStrMismatch(const char* file, int line, const char* msg, const char *result, const char* expected, int *failed, int *newFailed, int issue)
80 {
81     if (strcmp(result, expected) != 0) {
82         ++(*failed);
83         fprintf(stderr, "%s[%d]\t%s", file, line, msg);
84         if (issue)
85             fprintf(stderr, "\t[ISSUE %d]\n", issue);
86         else {
87             fprintf(stderr, "\t[NEW]\n");
88             ++(*newFailed);
89         }
90         fprintf(stderr, "\tResult   : %s\n", result);
91         fprintf(stderr, "\tExpected : %s\n", expected);
92     }
93 }
94 
float2str(const floatstruct * x)95 static const char* float2str(const floatstruct* x) {
96   static char buffer[350];
97 
98   float_getscientific(buffer, 110, x);
99   return buffer;
100 }
101 
DisplayErrorOnFloatMismatch(const char * file,int line,const char * msg,const floatstruct * result,const floatstruct * expected,int * failed,int * newFailed,int issue)102 void DisplayErrorOnFloatMismatch(const char* file, int line, const char* msg, const floatstruct* result, const floatstruct* expected, int *failed, int *newFailed, int issue)
103 {
104     int cmp;
105 
106     if (float_isnan(result) && float_isnan(expected))
107       cmp = 0;
108     else
109       cmp = float_cmp(expected, result);
110 
111     if (cmp != 0) {
112         ++(*failed);
113         fprintf(stderr, "%s[%d]\t%s", file, line, msg);
114         if (issue)
115             fprintf(stderr, "\t[ISSUE %d]\n", issue);
116         else {
117             fprintf(stderr, "\t[NEW]\n");
118             ++(*newFailed);
119         }
120         fprintf(stderr, "\tResult   : %s\n", float2str(result));
121         fprintf(stderr, "\tExpected : %s\n", float2str(expected));
122     }
123 }
124 
logequiv(int v1,int v2)125 static char logequiv(int v1, int v2)
126 {
127   return ((v1 == 0) && (v2 == 0))
128       || ((v1 != 0) && (v2 != 0));
129 }
130 
rol(unsigned u)131 static unsigned rol(unsigned u)
132 {
133   return (u << 1) | (u >> (sizeof(unsigned)*8-1));
134 }
135 
hash(floatnum x)136 static unsigned hash(floatnum x)
137 {
138   unsigned result;
139   bc_num bc;
140   char* p;
141   int i;
142 
143   result = 0;
144   if (x)
145   {
146     bc = x->significand;
147     result = rol(x->exponent) ^ (unsigned long)(bc);
148     if (bc)
149     {
150       result = rol(result) ^ bc->n_sign;
151       result = rol(result) ^ bc->n_len;
152       result = rol(result) ^ bc->n_scale;
153       p = bc->n_value;
154       result = rol(result) ^ (unsigned long)p;
155       for (i = 0; i++ <= bc->n_scale;)
156         result = rol(result) ^ *(p++);
157     }
158   }
159   return result;
160 }
161 
istruenan(floatnum x)162 static char istruenan(floatnum x)
163 {
164   return x->exponent == EXPNAN && x->significand == NULL;
165 }
166 
_cmp(floatnum v1,floatnum v2)167 static signed char _cmp(floatnum v1, floatnum v2)
168 {
169   if (float_isnan(v1) && float_isnan(v2))
170     return 0;
171   return float_cmp(v1, v2);
172 }
173 
mantcmp(bc_num b,const char * s)174 static char mantcmp(bc_num b, const char* s)
175 {
176   char* p;
177   int lg, i;
178 
179   p = b->n_value;
180   lg = strlen(s);
181   if (maxdigits < lg)
182     lg = maxdigits;
183   while (s[lg-1] == '0')
184     --lg;
185   if (lg != b->n_scale + 1)
186     return 0;
187   for (i = -1; ++i < lg;)
188     if (s[i] - '0' != *(p++))
189       return 0;
190   return 1;
191 }
192 
scmp(floatnum v,char * s)193 static int scmp(floatnum v, char* s)
194 {
195   char buf[30];
196 
197   float_getscientific(buf, 30, v);
198   return strcmp(buf, s) == 0;
199 }
200 
maxexp(char * buf,char * significand)201 static char* maxexp(char* buf, char* significand)
202 {
203   int lg;
204   lg = strlen(significand);
205   memcpy(buf, significand, lg);
206   sprintf(buf + lg, "%d", float_getrange());
207   return buf;
208 }
209 
minexp(char * buf,char * significand)210 static char* minexp(char* buf, char* significand)
211 {
212   int lg;
213   lg = strlen(significand);
214   memcpy(buf, significand, lg);
215   sprintf(buf+lg, "%d", -float_getrange()-1);
216   return buf;
217 }
218 
tc_fail(int i)219 static int tc_fail(int i)
220 {
221   printf("test case %d failed", i + 1);
222   return 0;
223 }
224 
tc_longadd(unsigned v1,unsigned v2,unsigned r1,unsigned r2)225 static int tc_longadd(unsigned v1, unsigned v2,
226                       unsigned r1, unsigned r2)
227 {
228   unsigned x1, x2, y1, y2;
229   x1 = v1;
230   x2 = v2;
231   y1 = v2;
232   y2 = v1;
233   _longadd(&x1, &x2);
234   _longadd(&y1, &y2);
235   return x1 == r1 && x2 == r2 && y1 == r1 && y2 == r2;
236 }
237 
test_longadd()238 static int test_longadd()
239 {
240 
241   static struct{
242     unsigned v1; unsigned v2; unsigned r1; unsigned r2;
243   } testcases[] = {
244     {0, 0, 0, 0},
245     {1, 2, 3, 0},
246     {msbu, 2, msbu+2, 0},
247     {1, msbu, msbu+1, 0},
248     {maxu-1, 1, maxu, 0},
249     {maxu, 1, 0, 1},
250     {maxu, maxu, maxu-1, 1},
251   };
252 
253   int i;
254 
255   printf("testing _longadd\n");
256   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
257     if(!tc_longadd(testcases[i].v1, testcases[i].v2,
258                    testcases[i].r1, testcases[i].r2)) return tc_fail(i);
259   return 1;
260 }
261 
tc_longmul(unsigned v1,unsigned v2,unsigned r1,unsigned r2)262 static int tc_longmul(unsigned v1, unsigned v2,
263                       unsigned r1, unsigned r2)
264 {
265   unsigned x1, x2, y1, y2;
266   x1 = v1;
267   x2 = v2;
268   y1 = v2;
269   y2 = v1;
270   _longmul(&x1, &x2);
271   _longmul(&y1, &y2);
272   return x1 == r1 && x2 == r2 && y1 == r1 && y2 == r2;
273 }
274 
test_longmul()275 static int test_longmul()
276 {
277   static struct{
278     unsigned v1; unsigned v2; unsigned r1; unsigned r2;
279   } testcases[] = {
280     {0, 0, 0, 0},
281     {0, 1, 0, 0},
282     {1, 2, 2, 0},
283     {msbu, 2, 0, 1},
284     {1, msbu, msbu, 0},
285     {maxu-1, 1, maxu-1, 0},
286     {maxu, 2, maxu-1, 1},
287     {maxu, maxu, 1, maxu-1},
288   };
289 
290   int i;
291 
292   printf("testing _longmul\n");
293   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
294     if(!tc_longmul(testcases[i].v1, testcases[i].v2,
295         testcases[i].r1, testcases[i].r2)) return tc_fail(i);
296   return 1;
297 }
298 
tc_longshr(unsigned v1,unsigned v2,char shift,unsigned result)299 static int tc_longshr(unsigned v1, unsigned v2, char shift,
300                       unsigned result)
301 {
302   unsigned r;
303   r = _longshr(v1, v2, shift);
304   return r == result;
305 }
306 
test_longshr()307 static int test_longshr()
308 {
309   static struct{
310     unsigned v1; unsigned v2; char shift; unsigned r;
311   } testcases[] = {
312     {0, 0, 5, 0},
313     {47, 12, 3, msbu+5},
314   };
315 
316   int i;
317 
318   printf("testing _longshr\n");
319   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
320     if(!tc_longshr(testcases[i].v1, testcases[i].v2,
321         testcases[i].shift, testcases[i].r)) return tc_fail(i);
322   return 1;
323 }
324 
tc_checkadd(int v1,int v2,char ok,int result)325 static int tc_checkadd(int v1, int v2, char ok, int result)
326 {
327   int x, y;
328   x = v1;
329   y = v2;
330   return _checkadd(&x, v2) == ok && _checkadd(&y, v1) == ok
331       && x == result && y == result;
332 }
333 
test_checkadd()334 static int test_checkadd()
335 {
336   static struct{
337     int v1; int v2; char ok; int r;
338   } testcases[] = {
339     {0, 0, 1, 0},
340     {1, 0, 1, 1},
341     {maxi, 0, 1, maxi},
342     {0, mini, 1, mini},
343     {maxi, 1, 0, mini},
344     {mini, -1, 0, maxi},
345   };
346 
347   int i;
348 
349   printf("testing _checkadd\n");
350   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
351     if(!tc_checkadd(testcases[i].v1, testcases[i].v2,
352         testcases[i].ok, testcases[i].r)) return tc_fail(i);
353   return 1;
354 }
355 
tc_checkmul(int v1,int v2,char ok,int result)356 static int tc_checkmul(int v1, int v2, char ok, int result)
357 {
358   int x, y;
359   x = v1;
360   y = v2;
361   return _checkmul(&x, v2) == ok && _checkmul(&y, v1) == ok
362       && x == result && y == result;
363 }
364 
test_checkmul()365 static int test_checkmul()
366 {
367   int i;
368 
369   static struct{
370     int v1; int v2; char ok; int r;
371   } testcases[] = {
372     {0, 0, 1, 0},
373     {1, 1, 1, 1},
374     {-1, 1, 1, -1},
375     {-1, -1, 1, 1},
376     {maxi, 1, 1, maxi},
377     {maxi, 2, 0, -2},
378     {1, mini, 1, mini},
379     {-1, mini, 0, mini},
380     {2, mini, 0, 0},
381   };
382 
383   printf("testing _checkmul\n");
384   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
385     if(!tc_checkmul(testcases[i].v1, testcases[i].v2,
386         testcases[i].ok, testcases[i].r)) return tc_fail(i);
387   return 1;
388 }
389 
tc_longarrayadd(unsigned x1,unsigned x2,unsigned x3,unsigned smd,unsigned r1,unsigned r2,unsigned r3,unsigned r4,int length)390 static int tc_longarrayadd(unsigned x1, unsigned x2, unsigned x3,
391  unsigned smd, unsigned r1, unsigned r2, unsigned r3, unsigned r4,
392  int length)
393 {
394   unsigned a[3];
395   unsigned r;
396 
397   a[0] = x1;
398   a[1] = x2;
399   a[2] = x3;
400   r = _longarrayadd(a, length, smd);
401   return a[0] == r1 && a[1] == r2 && a[2] == r3 && r == r4;
402 }
403 
test_longarrayadd()404 static int test_longarrayadd()
405 {
406   int i;
407 
408   static struct{
409     unsigned x1; unsigned x2; unsigned x3; unsigned smd;
410     unsigned r1; unsigned r2; unsigned r3; unsigned r4;
411     int lg;
412   } testcases[] = {
413     {0,0,0,0,0,0,0,0,0},
414     {0,0,0,0,0,0,0,0,3},
415     {1,2,3,4,5,2,3,0,3},
416     {maxu,2,3,4,3,3,3,0,3},
417     {maxu,maxu,3,4,3,0,4,0,3},
418     {maxu,maxu,maxu,4,3,0,0,1,3},
419     {0,0,0,1,0,0,0,1,0},
420     {1,0,0,1,2,0,0,0,1},
421     {maxu,0,0,1,0,0,0,1,1},
422   };
423 
424   printf("testing _longarrayadd\n");
425   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
426     if(!tc_longarrayadd(testcases[i].x1, testcases[i].x2,
427                         testcases[i].x3, testcases[i].smd,
428                         testcases[i].r1, testcases[i].r2,
429                         testcases[i].r3, testcases[i].r4,
430                         testcases[i].lg)) return tc_fail(i);
431   return 1;
432 }
433 
tc_longarraymul(unsigned x1,unsigned x2,unsigned x3,unsigned factor,unsigned r1,unsigned r2,unsigned r3,unsigned r4,int lg)434 static int tc_longarraymul(unsigned x1, unsigned x2, unsigned x3,
435   unsigned factor, unsigned r1, unsigned r2, unsigned r3, unsigned r4,
436   int lg)
437 {
438   unsigned a[3];
439   unsigned r;
440 
441   a[0] = x1;
442   a[1] = x2;
443   a[2] = x3;
444   r = _longarraymul(a, lg, factor);
445   return a[0] == r1 && a[1] == r2 && a[2] == r3 && r == r4;
446 }
447 
test_longarraymul()448 static int test_longarraymul()
449 {
450   int i;
451 
452   static struct{
453     unsigned x1; unsigned x2; unsigned x3; unsigned smd;
454     unsigned r1; unsigned r2; unsigned r3; unsigned r4;
455     int lg;
456   } testcases[] = {
457     {0,0,0,0,0,0,0,0,0},
458     {0,0,0,7,0,0,0,0,0},
459     {7,0,0,7,49,0,0,0,1},
460     {0,0,0,3,0,0,0,0,3},
461     {1,2,3,4,4,8,12,0,3},
462     {maxu,0,0,4,maxu-3,0,0,3,1},
463     {maxu,2,3,4,maxu-3,11,12,0,3},
464     {maxu,maxu,3,4,maxu-3,maxu,15,0,3},
465     {maxu,maxu,maxu,4,maxu-3,maxu,maxu,3,3},
466     {maxu,0,0,maxu,1,maxu-1,0,0,3},
467     {maxu,maxu,maxu,maxu,1,maxu,maxu,maxu-1,3},
468   };
469 
470   printf("testing _longarraymul\n");
471   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
472     if(!tc_longarraymul(testcases[i].x1, testcases[i].x2,
473         testcases[i].x3, testcases[i].smd,
474         testcases[i].r1, testcases[i].r2,
475         testcases[i].r3, testcases[i].r4,
476         testcases[i].lg)) return tc_fail(i);
477   return 1;
478 }
479 
tc_isnan(void * s,int exp,char result)480 static int tc_isnan(void* s, int exp, char result)
481 {
482   floatstruct f;
483 
484   float_geterror();
485   f.significand = s;
486   f.exponent = exp;
487   return float_isnan(&f) == result && exp == f.exponent
488          && f.significand == s && float_geterror() == Success;
489 }
490 
test_isnan()491 static int test_isnan()
492 {
493   static struct{
494     void* s; int exp; char result;
495   } testcases[] = {
496     {NULL, EXPNAN, 1},
497     {NULL, EXPZERO, 0},
498     {NULL, 0, 1},
499     {(void*)1, 0, 0},
500     {(void*)1, EXPNAN, 0},
501   };
502   int i;
503 
504   printf("testing float_isnan\n");
505 
506   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
507     if(!tc_isnan(testcases[i].s, testcases[i].exp,
508         testcases[i].result)) return tc_fail(i);
509   return 1;
510 }
511 
tc_iszero(void * s,int exp,char result)512 static int tc_iszero(void* s, int exp, char result)
513 {
514   floatstruct f;
515 
516   float_geterror();
517   f.significand = s;
518   f.exponent = exp;
519   return float_iszero(&f) == result && exp == f.exponent
520       && f.significand == s && float_geterror() == Success;
521 }
522 
test_iszero()523 static int test_iszero()
524 {
525   static struct{
526     void* s; int exp; char result;
527   } testcases[] = {
528     {NULL, EXPNAN, 0},
529     {NULL, EXPZERO, 1},
530     {NULL, 0, 0},
531     {(void*)1, 0, 0},
532     {(void*)1, EXPZERO, 0},
533   };
534   int i;
535 
536   printf("testing float_iszero\n");
537 
538   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
539     if(!tc_iszero(testcases[i].s, testcases[i].exp,
540         testcases[i].result)) return tc_fail(i);
541   return 1;
542 }
543 
tc_create(void * s,int exp)544 static int tc_create(void* s, int exp)
545 {
546   floatstruct f;
547 
548   float_geterror();
549   f.significand = s;
550   f.exponent = exp;
551   float_create(&f);
552   return istruenan(&f) && float_geterror() == Success;
553 }
554 
test_create()555 static int test_create()
556 {
557   static struct{
558     void* s; int exp;
559   } testcases[] = {
560     {NULL, EXPNAN},
561     {NULL, EXPZERO},
562     {NULL, 0},
563     {(void*)1, 0},
564     {(void*)1, EXPNAN},
565     {(void*)1, EXPZERO},
566   };
567   int i;
568 
569   printf("testing float_create\n");
570 
571   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
572     if(!tc_create(testcases[i].s, testcases[i].exp)) return tc_fail(i);
573   return 1;
574 }
575 
tc_setnan(char one,int exp)576 static int tc_setnan(char one, int exp)
577 {
578   floatstruct f;
579   int refs;
580 
581   float_geterror();
582   refs = _one_->n_refs;
583   f.significand = NULL;
584   if (one)
585     f.significand = bc_copy_num(_one_);
586   f.exponent = exp;
587   float_setnan(&f);
588   return istruenan(&f) && refs == _one_->n_refs
589          && float_geterror() == Success;
590 }
591 
test_setnan()592 static int test_setnan()
593 {
594   static struct{
595     char one; int exp;
596   } testcases[] = {
597     {0, EXPNAN},
598     {0, EXPZERO},
599     {0, 0},
600     {1, 0},
601     {1, EXPNAN},
602     {1, EXPZERO},
603   };
604   int i;
605 
606   printf("testing float_setnan\n");
607   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
608     if(!tc_setnan(testcases[i].one, testcases[i].exp)) return tc_fail(i);
609   return 1;
610 }
611 
tc_setzero(char one,int exp)612 static int tc_setzero(char one, int exp)
613 {
614   floatstruct f;
615   int refs;
616 
617   float_geterror();
618   refs = _one_->n_refs;
619   f.significand = NULL;
620   if (one)
621     f.significand = bc_copy_num(_one_);
622   f.exponent = exp;
623   float_setzero(&f);
624   return float_iszero(&f) && refs == _one_->n_refs
625         && float_geterror() == Success;
626 }
627 
test_setzero()628 static int test_setzero()
629 {
630   static struct{
631     char one; int exp;
632   } testcases[] = {
633     {0, EXPNAN},
634     {0, EXPZERO},
635     {0, 0},
636     {1, 0},
637     {1, EXPNAN},
638     {1, EXPZERO},
639   };
640   int i;
641 
642   printf("testing float_setzero\n");
643   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
644     if(!tc_setzero(testcases[i].one, testcases[i].exp)) return tc_fail(i);
645   return 1;
646 }
647 
tc_setsignificand(const char * mant,int mlg,const char * result,int dot,int zeros)648 static int tc_setsignificand(const char* mant, int mlg,
649                              const char* result, int dot, int zeros)
650 {
651   floatstruct f;
652   int refs;
653   int save;
654   int z, d, i;
655   char retvalue;
656 
657   float_create(&f);
658 
659   retvalue = 1;
660   float_geterror();
661   /* test zero or NaN cases */
662   if (result == NULL || result[0] == '0')
663   {
664     z = -1;
665     refs = _one_->n_refs;
666     f.exponent = 12;
667     f.significand = bc_copy_num(_one_);
668     f.significand->n_sign = MINUS;
669     d = float_setsignificand(&f, &z, mant, mlg);
670     if (result == NULL)
671       retvalue = istruenan(&f);
672     else if (result[0] == '0')
673       retvalue = float_iszero(&f);
674     retvalue = retvalue && refs == _one_->n_refs
675       && dot == d && z == zeros && float_geterror() == Success;
676   }
677   if (retvalue)
678   {
679     /* test NULL zeros pointer */
680     d = float_setsignificand(&f, NULL, mant, mlg);
681     if (result == NULL)
682       retvalue = istruenan(&f);
683     else if (result[0] == '0')
684       retvalue = float_iszero(&f);
685     else
686       retvalue = f.significand != NULL
687           && f.exponent == 0
688           && f.significand->n_len == 1
689           && f.significand->n_sign == PLUS
690           && mantcmp(f.significand, result);
691     retvalue = retvalue && dot == d && float_geterror() == Success;
692   }
693   if (retvalue && result != NULL && result[0] != '0')
694   {
695     save = maxdigits;
696     for (i = 0; retvalue && ++i <= save;)
697     {
698       maxdigits = i;
699       refs = _one_->n_refs;
700       f.exponent = 12;
701       f.significand = bc_copy_num(_one_);
702       f.significand->n_sign = MINUS;
703       z = -1;
704       d = float_setsignificand(&f, &z, mant, mlg);
705       retvalue = f.significand != NULL
706           && refs == _one_->n_refs
707           && f.significand->n_len == 1
708           && f.significand->n_sign == PLUS
709           && mantcmp(f.significand, result)
710           && dot == d && z == zeros
711           && f.exponent == 0
712           && float_geterror() == Success;
713     }
714     maxdigits = save;
715   }
716   _one_->n_sign = PLUS;
717   float_setnan(&f);
718   float_free(&f);
719   return retvalue;
720 }
721 
test_setsignificand()722 static int test_setsignificand()
723 {
724   static struct{
725     const char* mant; int lg; const char* result; int dot; int zeros;
726   } testcases[] = {
727     {NULL, -1, NULL, -1, 0},
728     {NULL, 0, NULL, -1, 0},
729     {"", NULLTERMINATED, NULL, -1, 0},
730     {".", NULLTERMINATED, NULL, -1, 0},
731     {"x", NULLTERMINATED, NULL, -1, 0},
732     {"-1", NULLTERMINATED, NULL, -1, 0},
733     {"+1", NULLTERMINATED, NULL, -1, 0},
734     {"1E", NULLTERMINATED, NULL, -1, 0},
735     {"1.E", NULLTERMINATED, NULL, -1, 0},
736     {"-1.E", NULLTERMINATED, NULL, -1, 0},
737     {"1E1", NULLTERMINATED, NULL, -1, 0},
738     {"1.E1", NULLTERMINATED, NULL, -1, 0},
739     {"1.1E1", NULLTERMINATED, NULL, -1, 0},
740     {"1.1e1", NULLTERMINATED, NULL, -1, 0},
741     {"1E+1", NULLTERMINATED, NULL, -1, 0},
742     {"1.E+1", NULLTERMINATED, NULL, -1, 0},
743     {"1.1E+1", NULLTERMINATED, NULL, -1, 0},
744     {"1.1e+1", NULLTERMINATED, NULL, -1, 0},
745     {"1.1(1)", NULLTERMINATED, NULL, -1, 0},
746     {"1.1(+1)", NULLTERMINATED, NULL, -1, 0},
747     {"+1E1", NULLTERMINATED, NULL, -1, 0},
748     {"+1.E1", NULLTERMINATED, NULL, -1, 0},
749     {"+1.1E1", NULLTERMINATED, NULL, -1, 0},
750     {"+1.1e1", NULLTERMINATED, NULL, -1, 0},
751     {"+1.1(1)", NULLTERMINATED, NULL, -1, 0},
752     {"+1.1(+1)", NULLTERMINATED, NULL, -1, 0},
753     {"-1.E1", NULLTERMINATED, NULL, -1, 0},
754     {"1.E-1", NULLTERMINATED, NULL, -1, 0},
755     {"-1.E-1", NULLTERMINATED, NULL, -1, 0},
756     {"1111111111111111111111E1", NULLTERMINATED, NULL, -1, 0},
757     {"E1", NULLTERMINATED, NULL, -1, 0},
758     {".e", NULLTERMINATED, NULL, -1, 0},
759     {".1e", NULLTERMINATED, NULL, -1, 0},
760     {"1.e1", NULLTERMINATED, NULL, -1, 0},
761     {"e1.", NULLTERMINATED, NULL, -1, 0},
762     {".1.", NULLTERMINATED, NULL, -1, 0},
763     {"1..", NULLTERMINATED, NULL, -1, 0},
764     {"1.000000000000000000.0", NULLTERMINATED, NULL, -1, 0},
765     {"0", NULLTERMINATED, "0", -1, 0},
766     {"0.", NULLTERMINATED, "0", -1, 0},
767     {".0", NULLTERMINATED, "0", -1, 0},
768     {"000", NULLTERMINATED, "0", -1, 0},
769     {"00000000000", NULLTERMINATED, "0", -1, 0},
770     {".00000000000", NULLTERMINATED, "0", -1, 0},
771     {"00000000000.", NULLTERMINATED, "0", -1, 0},
772     {"000000.00000", NULLTERMINATED, "0", -1, 0},
773     {"1", -1, NULL, -1, 0},
774     {"1", 0, NULL, -1, 0},
775     {"1", 1, "1", -1, 0},
776     {"1", NULLTERMINATED, "1", -1, 0},
777     {"12", 1, "1", -1, 0},
778     {"12", NULLTERMINATED, "12", -1, 0},
779     {".1", NULLTERMINATED, "1", 0, 0},
780     {"1.", NULLTERMINATED, "1", 1, 0},
781     {"1.2", NULLTERMINATED, "12", 1, 0},
782     {"01.2", NULLTERMINATED, "12", 2, 1},
783     {"00.000000000000012", NULLTERMINATED, "12", 2, 15},
784     {"12.3456789000", NULLTERMINATED, "123456789", 2, 0},
785     {"12345678900.0", NULLTERMINATED, "123456789", 11, 0},
786     {"12345678901", NULLTERMINATED, "12345678901", -1, 0},
787     {"123456789012", NULLTERMINATED, "12345678901", -1, 0},
788     {"1.2345678901", NULLTERMINATED, "12345678901", 1, 0},
789     {"0.12345678901", NULLTERMINATED, "12345678901", 1, 1},
790     {"0.012345678901", NULLTERMINATED, "12345678901", 1, 2},
791     {"1234567890183456789", NULLTERMINATED, "12345678901", -1, 0},
792     {"12345678900123456789", NULLTERMINATED, "123456789", -1, 0},
793     {"12345678901234567.89", NULLTERMINATED, "12345678901", 17, 0},
794   };
795   int i, save;
796 
797   printf("testing float_setsignificand\n");
798   save = maxdigits;
799   maxdigits = 11;
800   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
801     if(!tc_setsignificand(testcases[i].mant, testcases[i].lg,
802         testcases[i].result, testcases[i].dot, testcases[i].zeros))
803       return tc_fail(i);
804   maxdigits = save;
805   return 1;
806 }
807 
tc_getsignificand(const char * value,int bufsz,const char * result)808 static int tc_getsignificand(const char* value, int bufsz, const char* result)
809 {
810   char buf[30];
811   int lg, i, j;
812   unsigned h;
813   floatstruct f;
814   char retvalue;
815 
816   static int exp[] = {-2, -1, 0, 1, 2, EXPNAN, EXPZERO, MAXEXP, -MAXEXP-1};
817   static int sign[] = {PLUS, MINUS};
818 
819   float_create(&f);
820   float_setsignificand(&f, NULL, value, NULLTERMINATED);
821   float_geterror();
822   if (float_isnan(&f) || float_iszero(&f))
823   {
824     memset(buf, '?', 30);
825     h = hash(&f);
826     lg = strlen(result);
827     retvalue = float_getsignificand(buf+1, bufsz, &f) == lg
828         && buf[0] == '?'
829         && buf[lg + 1] == '?'
830         && memcmp(buf + 1, result, lg) == 0
831         && h == hash(&f)
832         && float_geterror() == Success;
833   }
834   else
835     for (i = sizeof(exp)/sizeof(int); --i >= 0;)
836       for (j = -1; ++j < 2;)
837       {
838         lg = strlen(result);
839         memset(buf, '?', 30);
840         f.significand->n_sign = sign[j];
841         f.exponent = exp[i];
842         h = hash(&f);
843         retvalue = float_getsignificand(buf+1, bufsz, &f) == lg
844           && h == hash(&f)
845           && buf[0] == '?'
846           && buf[lg + 1] == '?'
847           && memcmp(buf + 1, result, lg) == 0
848           && float_geterror() == Success;
849       }
850   float_free(&f);
851   return retvalue;
852 }
853 
test_getsignificand()854 static int test_getsignificand()
855 {
856   static const char v1[] = "1";
857   static const char v2[] = "12345678901";
858   static struct{
859     const char* value; int bufsz; const char* result;
860   } testcases[] = {
861     {v1, -1, ""},
862     {v1, 0, ""},
863     {v1, 1, "1"},
864     {v1, 2, "1"},
865     {"N", 0, ""},
866     {"N", 1, "N"},
867     {"N", 2, "N"},
868     {"0", 0, ""},
869     {"0", 1, "0"},
870     {"0", 2, "0"},
871     {v2, 1, "1"},
872     {v2, 2, "12"},
873     {v2, 10, "1234567890"},
874     {v2, 11, "12345678901"},
875     {v2, 12, "12345678901"},
876   };
877   int i;
878 
879   printf("testing float_getsignificand\n");
880 
881   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
882     if(!tc_getsignificand(testcases[i].value,
883         testcases[i].bufsz, testcases[i].result))
884       return tc_fail(i);
885   return 1;
886 }
887 
tc_setexponent(const char * value,int exp,int range,int result,char valid)888 static int tc_setexponent(const char* value, int exp, int range,
889                           int result, char valid)
890 {
891   floatstruct f;
892   int save, i;
893   char buf[30];
894   static int sign[] = {PLUS, MINUS};
895 
896   save = float_setrange(range);
897   float_geterror();
898   float_create(&f);
899   for (i = -1; ++i < 2;)
900   {
901     float_setsignificand(&f, NULL, value, NULLTERMINATED);
902     if (!float_isnan(&f) && !float_iszero(&f))
903     {
904       f.exponent = -123;
905       f.significand->n_sign = sign[i];
906     }
907     float_setexponent(&f, exp);
908     buf[float_getsignificand(buf, 30, &f)] = '\0';
909     if (valid)
910     {
911       if (strcmp(buf, value) != 0 || f.exponent != result
912         || (f.significand && f.significand->n_sign != sign[i]))
913         return 0;
914     }
915     else if(!istruenan(&f))
916       return 0;
917   }
918   float_free(&f);
919   float_setrange(save);
920   return float_geterror() == Success;
921 }
922 
test_setexponent()923 static int test_setexponent()
924 {
925   int i;
926   static struct{
927     const char* mant; int exp; int range; int result; char valid;
928   } testcases[] = {
929     {"N", 0, 100, EXPNAN, 1},
930     {"N", 1, 100, EXPNAN, 1},
931     {"N", -1, 100, EXPNAN, 1},
932     {"N", EXPNAN, 100, EXPNAN, 1},
933     {"N", 100, 100, EXPNAN, 1},
934     {"N", EXPZERO, 100, EXPNAN, 1},
935     {"0", 0, 100, EXPZERO, 1},
936     {"0", 1, 100, EXPZERO, 1},
937     {"0", -1, 100, EXPZERO, 1},
938     {"0", EXPNAN, 100, EXPZERO, 1},
939     {"0", EXPNAN - 1, 100, EXPZERO, 1},
940     {"0", EXPZERO, 100, EXPZERO, 1},
941     {"1", 0, 100, 0, 1},
942     {"12", 100, 100, 100, 1},
943     {"12", 101, 100, 0, 0},
944     {"13", -101, 100, -101, 1},
945     {"121", -102, 100, 0, 0},
946     {"1432", EXPNAN, 100, 0, 0},
947     {"1432", EXPZERO, 100, 0, 0},
948     {"1432", MAXEXP, MAXEXP, MAXEXP, 1},
949     {"1432", -MAXEXP-1, MAXEXP, -MAXEXP-1, 1},
950   };
951 
952   printf("testing float_setexponent\n");
953 
954   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
955     if(!tc_setexponent(testcases[i].mant, testcases[i].exp,
956         testcases[i].range, testcases[i].result, testcases[i].valid))
957       return tc_fail(i);
958   return 1;
959 }
960 
tc_getexponent(const char * value,int exp,int result)961 static int tc_getexponent(const char* value, int exp, int result)
962 {
963   floatstruct f;
964   unsigned h;
965   char retvalue;
966 
967   float_create(&f);
968   float_setsignificand(&f, NULL, value, NULLTERMINATED);
969   if (!float_isnan(&f) && !float_iszero(&f))
970     float_setexponent(&f, exp);
971   h = hash(&f);
972   float_geterror();
973   retvalue = float_getexponent(&f) == result && hash(&f) == h
974              && float_geterror() == Success;
975   float_free(&f);
976   return retvalue;
977 }
978 
test_getexponent()979 static int test_getexponent()
980 {
981   static struct{
982     const char* value; int exp; int result;
983   } testcases[] = {
984     {"N", 0, 0},
985     {"0", 0, 0},
986     {"1", 0, 0},
987     {"1234", 5, 5},
988     {"24413", -7, -7},
989     {"623", MAXEXP, MAXEXP},
990     {"6355", -MAXEXP-1, -MAXEXP-1},
991   };
992   int i, save;
993 
994   printf("testing float_getexponent\n");
995 
996   save = float_setrange(MAXEXP);
997   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
998     if(!tc_getexponent(testcases[i].value, testcases[i].exp, testcases[i].result))
999       return tc_fail(i);
1000   float_setrange(save);
1001   return 1;
1002 }
1003 
tc_setsign(const char * value,int exp)1004 static int tc_setsign(const char* value, int exp)
1005 {
1006   floatstruct f;
1007   unsigned h, hm;
1008   int i;
1009 
1010   static signed char invsign[] = {2, -2, 127, 126, -128, -127};
1011 
1012   float_create(&f);
1013   float_setsignificand(&f, NULL, value, NULLTERMINATED);
1014   float_setexponent(&f, exp);
1015   h = hash(&f);
1016   if (f.significand)
1017     f.significand->n_sign = MINUS;
1018   hm = hash(&f);
1019   float_geterror();
1020   float_setsign(&f, 0);
1021   if ((f.significand && f.significand->n_sign != MINUS) || hm != hash(&f))
1022     return 0;
1023   float_setsign(&f, 1);
1024   if ((f.significand && f.significand->n_sign != PLUS) || h != hash(&f))
1025     return 0;
1026   float_setsign(&f, 0);
1027   if ((f.significand && f.significand->n_sign != PLUS) || h != hash(&f))
1028     return 0;
1029   float_setsign(&f, 1);
1030   if ((f.significand && f.significand->n_sign != PLUS) || h != hash(&f))
1031     return 0;
1032   float_setsign(&f, -1);
1033   if ((f.significand && f.significand->n_sign != MINUS) || hm != hash(&f))
1034     return 0;
1035   float_setsign(&f, -1);
1036   if ((f.significand && f.significand->n_sign != MINUS) || hm != hash(&f))
1037     return 0;
1038   for (i = sizeof(invsign)/sizeof(signed char); --i >= 0;)
1039   {
1040     float_setsignificand(&f, NULL, value, NULLTERMINATED);
1041     float_setexponent(&f, exp);
1042     float_setsign(&f, invsign[i]);
1043     if (!istruenan(&f))
1044       return 0;
1045   }
1046   return float_geterror() == Success;
1047 }
1048 
test_setsign()1049 static int test_setsign()
1050 {
1051   int i;
1052   static struct{
1053     const char* value; int exp;
1054   } testcases[] = {
1055     {"N", 0},
1056     {"0", 0},
1057     {"1", 0},
1058     {"123", 12},
1059     {"18766", -12},
1060   };
1061 
1062   printf("testing float_setsign\n");
1063 
1064   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1065     if(!tc_setsign(testcases[i].value, testcases[i].exp))
1066       return tc_fail(i);
1067   return 1;
1068 }
1069 
tc_getsign(const char * value,int exp,signed char sign,signed char result)1070 static int tc_getsign(const char* value, int exp, signed char sign, signed char result)
1071 {
1072   floatstruct f;
1073   unsigned h;
1074   char retvalue;
1075 
1076   float_create(&f);
1077   float_setsignificand(&f, NULL, value, NULLTERMINATED);
1078   float_setsign(&f, sign);
1079   float_setexponent(&f, exp);
1080   h = hash(&f);
1081   float_geterror();
1082   retvalue = float_getsign(&f) == result && hash(&f) == h
1083              && float_geterror() == Success;
1084   float_free(&f);
1085   return retvalue;
1086 }
1087 
test_getsign()1088 static int test_getsign()
1089 {
1090   int i;
1091   static struct{
1092     const char* mant; int exp; signed char sign; signed char result;
1093   } testcases[] = {
1094     {"N", 0, 0, 0},
1095     {"0", 0, 0, 0},
1096     {"1", 0, 1, 1},
1097     {"123", 0, -1, -1},
1098     {"281", 3772, 1, 1},
1099     {"373", 31912, -1, -1},
1100     {"232", -233, 1, 1},
1101     {"123", -1442, -1, -1},
1102   };
1103 
1104   printf("testing float_getsign\n");
1105 
1106   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1107     if(!tc_getsign(testcases[i].mant, testcases[i].exp,
1108         testcases[i].sign, testcases[i].result)) return tc_fail(i);
1109   return 1;
1110 }
1111 
tc_getlength(const char * value,int result)1112 static int tc_getlength(const char* value, int result)
1113 {
1114   floatstruct f;
1115   int i;
1116   int save;
1117   unsigned h;
1118 
1119   static int exp[] = {0, -1, 1, MAXEXP, -MAXEXP-1};
1120 
1121   save = float_setrange(MAXEXP);
1122   float_create(&f);
1123   float_setsignificand(&f, NULL, value, NULLTERMINATED);
1124   float_geterror();
1125   if (float_isnan(&f) || float_iszero(&f))
1126   {
1127     h = hash(&f);
1128     if (float_getlength(&f) != 0 || h != hash(&f))
1129       return 0;
1130   }
1131   else
1132   {
1133     for (i = sizeof(exp)/sizeof(int); --i >= 0;)
1134     {
1135       float_setexponent(&f, exp[i]);
1136       h = hash(&f);
1137       if (float_getlength(&f) != result || h != hash(&f))
1138         return 0;
1139       float_setsign(&f, -1);
1140       h = hash(&f);
1141       if (float_getlength(&f) != result || h != hash(&f))
1142         return 0;
1143     }
1144   }
1145   float_free(&f);
1146   float_setrange(save);
1147   return float_geterror() == Success;
1148 }
1149 
test_getlength()1150 static int test_getlength()
1151 {
1152   int i;
1153   static struct{
1154     const char* mant; int result;
1155   } testcases[] = {
1156     {"N", 0},
1157     {"0", 0},
1158     {"1", 1},
1159     {"12", 2},
1160     {"123", 3},
1161     {"1234", 4},
1162     {"12345", 5},
1163     {"123456", 6},
1164     {"1234567", 7},
1165     {"12345678", 8},
1166     {"123456789", 9},
1167   };
1168 
1169   printf("testing float_getlength\n");
1170 
1171   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1172     if(!tc_getlength(testcases[i].mant, testcases[i].result))
1173       return tc_fail(i);
1174   return 1;
1175 }
1176 
tc_getdigit(const char * value)1177 static int tc_getdigit(const char* value)
1178 {
1179   floatstruct f;
1180   int i, j, k, save, lg;
1181   unsigned h;
1182 
1183   static signed char sign[] = {1, -1};
1184   static int exp[] = {0, -1, 1, MAXEXP, -MAXEXP-1};
1185 
1186   float_create(&f);
1187   float_setsignificand(&f, NULL, value, NULLTERMINATED);
1188   float_geterror();
1189   if (float_getlength(&f) == 0)
1190   {
1191     h = hash(&f);
1192     for (k = -5; ++k < 5;)
1193       if (float_getdigit(&f, k) != 0 || h != hash(&f))
1194         return 0;
1195   }
1196   else
1197   {
1198     lg = strlen(value);
1199     save = float_setrange(MAXEXP);
1200     for (i = sizeof(exp)/sizeof(exp[0]); --i >= 0;)
1201       for (j = -1; ++j < 2;)
1202       {
1203         float_setexponent(&f, exp[i]);
1204         float_setsign(&f, sign[j]);
1205         h = hash(&f);
1206         for (k = lg + 3; --k > -3;)
1207           if (k < 0 || k >= lg)
1208           {
1209             if (float_getdigit(&f, k) != 0 || h != hash(&f))
1210               return 0;
1211           }
1212           else if (float_getdigit(&f, k) != value[k] - '0' || h != hash(&f))
1213             return 0;
1214       }
1215     float_setrange(save);
1216   }
1217   float_free(&f);
1218   return float_geterror() == Success;
1219 }
1220 
test_getdigit()1221 static int test_getdigit()
1222 {
1223   int i;
1224   static struct{
1225     const char* mant;
1226   } testcases[] = {
1227     {"N"},
1228     {"0"},
1229     {"1"},
1230     {"12"},
1231     {"123"},
1232     {"123456789"},
1233     {"104"},
1234   };
1235 
1236   printf("testing float_getdigit\n");
1237   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1238     if(!tc_getdigit(testcases[i].mant)) return tc_fail(i);
1239   return 1;
1240 }
1241 
tc_getscientific(const char * s,int exp,int sz,const char * result)1242 static int tc_getscientific(const char* s, int exp, int sz, const char* result)
1243 {
1244   floatstruct f;
1245   char r[30];
1246   char buf[30];
1247   int lg;
1248   unsigned h;
1249 
1250   float_create(&f);
1251   float_setsignificand(&f, NULL, s, NULLTERMINATED);
1252   float_setexponent(&f, exp);
1253   memset(buf, '?', 30);
1254   h = hash(&f);
1255   float_geterror();
1256   lg = strlen(result);
1257   r[0] = '\0';
1258   if (lg == 0)
1259   {
1260     if (float_getscientific(buf+1, sz, &f) != -1
1261            || h != hash(&f)
1262            || buf[0] != '?'
1263            || buf[1] != '?')
1264       return 0;
1265   }
1266   else
1267   {
1268     memcpy(r, result, lg+1);
1269     if (float_getlength(&f) != 0)
1270       sprintf(r + lg, "%d", exp);
1271     lg = strlen(r);
1272     if (float_getscientific(buf+1, sz, &f) != lg
1273         || h != hash(&f)
1274         || buf[0] != '?'
1275         || buf[lg + 2] != '?'
1276         || memcmp(buf + 1, r, lg) != 0)
1277       return 0;
1278     if (float_getlength(&f) != 0)
1279     {
1280       float_setsign(&f, -1);
1281       h = hash(&f);
1282       if (float_getscientific(buf+1, sz+1, &f) != lg+1
1283           || h != hash(&f)
1284           || buf[0] != '?'
1285           || buf[lg + 3] != '?'
1286           || buf[1] != '-'
1287           || memcmp(buf + 2, r, lg) != 0)
1288         return 0;
1289     }
1290   }
1291   float_free(&f);
1292   return float_geterror() == Success;
1293 }
1294 
test_getscientific()1295 static int test_getscientific()
1296 {
1297   int i;
1298   static struct{
1299     const char* mant; int exp; int sz; const char* result;
1300   } testcases[] = {
1301     {"N", 0, -1, ""},
1302     {"N", 0, 0, ""},
1303     {"N", 0, 1, ""},
1304     {"N", 0, 2, ""},
1305     {"N", 0, 3, ""},
1306     {"N", 0, 4, "NaN"},
1307     {"N", 0, 5, "NaN"},
1308     {"0", 0, -1, ""},
1309     {"0", 0, 0, ""},
1310     {"0", 0, 1, ""},
1311     {"0", 0, 2, "0"},
1312     {"0", 0, 3, "0"},
1313     {"1", 0, -1, ""},
1314     {"1", 0, 0, ""},
1315     {"1", 0, 1, ""},
1316     {"1", 0, 2, ""},
1317     {"1", 0, 3, ""},
1318     {"1", 0, 4, ""},
1319     {"1", 0, 5, "1.e"},
1320     {"1", 0, 6, "1.e"},
1321     {"12", 0, 4, ""},
1322     {"12", 0, 5, "1.e"},
1323     {"12", 0, 6, "1.2e"},
1324     {"12", 0, 7, "1.2e"},
1325     {"12", 10, 5, ""},
1326     {"12", 10, 6, "1.e"},
1327     {"12", 10, 7, "1.2e"},
1328     {"12", 10, 8, "1.2e"},
1329     {"12345678001", 10, 12, "1.234567e"},
1330     {"12345678001", 10, 13, "1.2345678e"},
1331     {"12345678001", 10, 14, "1.23456780e"},
1332     {"12345678001", 10, 15, "1.234567800e"},
1333     {"12345678001", 10, 16, "1.2345678001e"},
1334     {"12345678001", -10, 13, "1.234567e"},
1335     {"12345678001", -10, 14, "1.2345678e"},
1336     {"12345678001", -10, 15, "1.23456780e"},
1337     {"12345678001", -10, 16, "1.234567800e"},
1338     {"12345678001", -10, 17, "1.2345678001e"},
1339     {"12", 1, 6, "1.2e"},
1340     {"12", -1, 7, "1.2e"},
1341     {"12", MAXEXP, 25, "1.2e"},
1342     {"12", -MAXEXP-1, 25, "1.2e"},
1343   };
1344   int save;
1345 
1346   printf("testing float_getscientific\n");
1347   save = float_setrange(MAXEXP);
1348   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1349     if(!tc_getscientific(testcases[i].mant, testcases[i].exp,
1350         testcases[i].sz, testcases[i].result)) return tc_fail(i);
1351   float_setrange(save);
1352   return 1;
1353 }
1354 
tc_setscientific(const char * value,const char * result)1355 static int tc_setscientific(const char* value, const char* result)
1356 {
1357   floatstruct f;
1358   char v[40];
1359   char buf[30];
1360   int sz, refs;
1361   signed char sign;
1362 
1363   float_create(&f);
1364   float_geterror();
1365   refs = _one_->n_refs;
1366   f.exponent = 12;
1367   f.significand = bc_copy_num(_one_);
1368   float_setscientific(&f, value, NULLTERMINATED);
1369   float_getscientific(buf, sizeof(buf), &f);
1370   if (refs != _one_->n_refs || strcmp(buf, result) != 0)
1371     return 0;
1372   sz = strlen(value);
1373   memset(v, '1', sizeof(v));
1374   memcpy(v+1, value, sz);
1375   float_setscientific(&f, v+1, sz);
1376   float_getscientific(buf, sizeof(buf), &f);
1377   if (strcmp(buf, result) != 0)
1378     return 0;
1379   v[0] = '+';
1380   float_setscientific(&f, v, sz+1);
1381   float_getscientific(buf, sizeof(buf), &f);
1382   if (strcmp(buf, result) != 0)
1383     return 0;
1384   v[0] = '-';
1385   float_setscientific(&f, v, sz+1);
1386   sign = float_getsign(&f);
1387   float_setsign(&f, 1);
1388   float_getscientific(buf, sizeof(buf), &f);
1389   if (sign > 0 || strcmp(buf, result) != 0)
1390     return 0;
1391   float_free(&f);
1392   return float_geterror() == Success;
1393 }
1394 
test_setscientific()1395 static int test_setscientific()
1396 {
1397   int i;
1398   static struct{
1399     const char* value; const char* result;
1400   } testcases[] = {
1401     {"", "NaN"},
1402     {"E", "NaN"},
1403     {".", "NaN"},
1404     {"x", "NaN"},
1405     {"0Ex", "NaN"},
1406     {"0xEx", "NaN"},
1407     {"EE0", "NaN"},
1408     {"00.0.0", "NaN"},
1409     {"0", "0"},
1410     {"0E0", "0"},
1411     {"0E+0", "0"},
1412     {"0E-0", "0"},
1413     {"0E+999999999999999999999999999999", "0"},
1414     {"0E-999999999999999999999999999999", "0"},
1415     {"0000", "0"},
1416     {".0000", "0"},
1417     {"0000.", "0"},
1418     {"00.00", "0"},
1419     {"0000E1", "0"},
1420     {".0000E-1", "0"},
1421     {"0000.E+12", "0"},
1422     {"00.00E-13", "0"},
1423     {"1", "1.e0"},
1424     {"9", "9.e0"},
1425     {"1.", "1.e0"},
1426     {"1.0", "1.e0"},
1427     {"10", "1.e1"},
1428     {"0.1", "1.e-1"},
1429     {"100", "1.e2"},
1430     {"0.01", "1.e-2"},
1431     {"1E0", "1.e0"},
1432     {"1e0", "1.e0"},
1433     {"01e0", "1.e0"},
1434     {"01.e0", "1.e0"},
1435     {"1e1", "1.e1"},
1436     {"1e-1", "1.e-1"},
1437     {"1.e-1", "1.e-1"},
1438     {"1.0e-1", "1.e-1"},
1439     {"01.0e-1", "1.e-1"},
1440     {"0.1e-1", "1.e-2"},
1441     {"10e-1", "1.e0"},
1442     {"100e-1", "1.e1"},
1443     {"1e1000", "1.e1000"},
1444     {"1e-1000", "1.e-1000"},
1445     {"1.234567890123456789e0", "1.23456789012345e0"},
1446     {"1E3000000000000000000000000000000", "NaN"},
1447     {"1E-3000000000000000000000000000000", "NaN"},
1448   };
1449   int save;
1450   char buf[30];
1451 
1452   printf("testing float_setscientific, 1. block\n");
1453   save = float_setrange(MAXEXP);
1454   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1455     if(!tc_setscientific(testcases[i].value, testcases[i].result))
1456       return tc_fail(i);
1457   float_setrange(save);
1458   printf("testing float_setscientific, 2. block\n");
1459   maxexp(buf, "2.e");
1460   /* maximum exponent 2.eMAXEXP */
1461   if (!tc_setscientific(buf, buf)) return tc_fail(0);
1462   buf[1] = '0';
1463   /* combined overflow 20eMAXEXP */
1464   if (!tc_setscientific(buf, "NaN")) return tc_fail(1);
1465   ++buf[strlen(buf)-1];
1466   buf[1] = '.';
1467   /* overflow limit 2.e(MAXEXP+1) */
1468   if (!tc_setscientific(buf, "NaN")) return tc_fail(2);
1469   minexp(buf, "1.e");
1470   /* minimum exponent */
1471   if (!tc_setscientific(buf, buf)) return tc_fail(3);
1472   buf[0] = '.';
1473   buf[1] = '1';
1474   /* combined underflow */
1475   if (!tc_setscientific(buf, "NaN")) return tc_fail(4);
1476   buf[0] = '1';
1477   buf[1] = '.';
1478   ++buf[strlen(buf)-1];
1479   /* underflow limit */
1480   if (!tc_setscientific(buf, "NaN")) return tc_fail(5);
1481   return 1;
1482 }
1483 
tc_setinteger(int value)1484 static int tc_setinteger(int value)
1485 {
1486   floatstruct f, g;
1487   char buf[50];
1488   char r[50];
1489   int err;
1490 
1491   sprintf(r, "%d", value);
1492   float_create(&f);
1493   float_create(&g);
1494   float_geterror();
1495   float_setinteger(&f, value);
1496   err = float_geterror();
1497   float_setasciiz(&g, r);
1498   float_getscientific(buf, 50, &f);
1499   float_getscientific(r, 50, &g);
1500   float_free(&f);
1501   float_free(&g);
1502   return strcmp(buf, r) == 0 && err == Success;
1503 }
1504 
test_setinteger()1505 static int test_setinteger()
1506 {
1507   int i;
1508   static struct{
1509     int value;
1510   } testcases[] = {
1511     {0},
1512     {1},
1513     {9},
1514     {10},
1515     {-1},
1516     {-9},
1517     {-10},
1518     {maxi},
1519     {mini},
1520   };
1521 
1522   printf("testing float_setinteger\n");
1523 
1524   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1525     if(!tc_setinteger(testcases[i].value))
1526       return tc_fail(i);
1527   return 1;
1528 }
1529 
tc_neg(const char * value,signed char result,int error)1530 static int tc_neg(const char* value, signed char result, int error)
1531 {
1532   floatstruct f;
1533   unsigned h;
1534   int errcode;
1535   signed char sign;
1536   char retvalue;
1537   char err;
1538 
1539   float_create(&f);
1540   float_setasciiz(&f, value);
1541   h = hash(&f);
1542   float_geterror();
1543   err = float_neg(&f);
1544   errcode = float_geterror();
1545   sign = float_getsign(&f);
1546   if (sign != 0)
1547     float_neg(&f);
1548   retvalue = result == sign && h == hash(&f) && errcode == error
1549              && logequiv(errcode, !err);
1550   float_free(&f);
1551   return retvalue;
1552 }
1553 
test_neg()1554 static int test_neg()
1555 {
1556   int i;
1557   static struct{
1558     const char* value; signed char result; int error;
1559   } testcases[] = {
1560     {"NaN", 0, NoOperand},
1561     {"0", 0, Success},
1562     {"1.23", -1, Success},
1563     {"-1.23", 1, Success},
1564   };
1565 
1566   printf("testing float_changesign\n");
1567   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1568     if(!tc_neg(testcases[i].value, testcases[i].result,
1569                testcases[i].error))
1570       return tc_fail(i);
1571   return 1;
1572 }
1573 
tc_abs(const char * value,int error)1574 static int tc_abs(const char* value, int error)
1575 {
1576   floatstruct f;
1577   unsigned h;
1578   int errcode;
1579   signed char sign;
1580   char err, retvalue;
1581 
1582   float_create(&f);
1583   float_setasciiz(&f, value);
1584   sign = float_getsign(&f);
1585   h = hash(&f);
1586   float_geterror();
1587   err = float_abs(&f);
1588   errcode = float_geterror();
1589   if (sign)
1590     retvalue = float_getsign(&f) == 1;
1591   else
1592     retvalue = float_getsign(&f) == 0;
1593   float_setsign(&f, sign);
1594   retvalue = retvalue && h == hash(&f) && error == errcode
1595              && logequiv(!err, errcode);
1596   float_free(&f);
1597   return retvalue;
1598 }
1599 
test_abs()1600 static int test_abs()
1601 {
1602   int i;
1603   static struct{
1604     const char* value; int error;
1605   } testcases[] = {
1606     {"NaN", NoOperand},
1607     {"0", Success},
1608     {"1.23", Success},
1609     {"-1.23", Success},
1610   };
1611 
1612   printf("testing float_abs\n");
1613   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1614     if(!tc_abs(testcases[i].value, testcases[i].error))
1615       return tc_fail(i);
1616   return 1;
1617 }
1618 
tc_cmp(const char * val1,const char * val2,signed char result)1619 static int tc_cmp(const char* val1, const char* val2, signed char result)
1620 {
1621   floatstruct v1;
1622   floatstruct v2;
1623   signed char revres, res;
1624 
1625   float_create(&v1);
1626   float_create(&v2);
1627   float_setscientific(&v1, val1, NULLTERMINATED);
1628   float_setscientific(&v2, val2, NULLTERMINATED);
1629   float_geterror();
1630   revres = float_cmp(&v2, &v1);
1631   if (revres != UNORDERED)
1632     revres = -revres;
1633   else if (float_geterror() != NoOperand)
1634     return 0;
1635   res = float_cmp(&v1, &v2);
1636   if (res == UNORDERED && float_geterror() != NoOperand)
1637     return 0;
1638   float_free(&v1);
1639   float_free(&v2);
1640   return res == result && revres == result && float_geterror() == Success;
1641 }
1642 
test_cmp()1643 static int test_cmp()
1644 {
1645   int i;
1646   static struct{
1647     const char* value1; const char* value2; signed char result;
1648   } testcases[] = {
1649     {"NaN", "NaN", UNORDERED},
1650     {"NaN", "0", UNORDERED},
1651     {"NaN", "1", UNORDERED},
1652     {"NaN", "-1", UNORDERED},
1653     {"0", "0", 0},
1654     {"1", "0", 1},
1655     {"10", "0", 1},
1656     {".1", "0", 1},
1657     {"-1", "0", -1},
1658     {"-10", "0", -1},
1659     {"-.1", "0", -1},
1660     {"1", "10", -1},
1661     {"1", "1", 0},
1662     {"1", ".1", 1},
1663     {"1", "-10", 1},
1664     {"1", "-1", 1},
1665     {"1", "-.1", 1},
1666     {"-1", "10", -1},
1667     {"-1", ".1", -1},
1668     {"-1", "-10", 1},
1669     {"-1", "-.1", -1},
1670     {"-1", "-1", 0},
1671     {"1.01", "1", 1},
1672     {"1.01", "1.02", -1},
1673     {"1.021", "1.011", 1},
1674     {"1.011", "1.01", 1},
1675     {"1.011", "1.011", 0},
1676     {"-1.01", "-1", -1},
1677     {"-1.01", "-1.02", 1},
1678     {"-1.021", "-1.011", -1},
1679     {"-1.011", "-1.01", -1},
1680     {"-1.011", "-1.011", 0},
1681   };
1682 
1683   printf("testing float_cmp\n");
1684 
1685   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1686     if(!tc_cmp(testcases[i].value1, testcases[i].value2, testcases[i].result))
1687       return tc_fail(i);
1688   return 1;
1689 }
1690 
tc_copy(const char * source,int digits,int error,const char * result)1691 static int tc_copy(const char* source, int digits,
1692                     int error, const char* result)
1693 {
1694   floatstruct src, dest;
1695   floatnum s, d;
1696   int refs, save, code;
1697   char err, retvalue;
1698   char buf[60];
1699 
1700   refs = _one_->n_refs;
1701   float_create(&src);
1702   float_create(&dest);
1703   s = &src;
1704   d = &dest;
1705   dest.significand = bc_copy_num(_one_);
1706   dest.exponent = 12;
1707   save = float_setprecision(50);
1708   float_setasciiz(s, source);
1709   float_setprecision(save);
1710   float_geterror();
1711   err = float_copy(d, s, digits);
1712   code = float_geterror();
1713   float_getscientific(buf, sizeof(buf), d);
1714   retvalue = refs == _one_->n_refs
1715              && code == error
1716              && logequiv(code, !err)
1717              && strcmp(result, buf) == 0;
1718   if (retvalue)
1719   {
1720     err = float_copy(s, s, digits);
1721     code = float_geterror();
1722     float_getscientific(buf, sizeof(buf), d);
1723     retvalue = code == error
1724         && logequiv(code, !err)
1725         && strcmp(result, buf) == 0;
1726   }
1727   float_free(s);
1728   float_free(d);
1729   return retvalue;
1730 }
1731 
test_copy()1732 static int test_copy()
1733 {
1734   int i;
1735   static struct{
1736     const char* src; int digits; const char* result; int error;
1737   } testcases[] = {
1738     {"NaN", -10, "NaN", InvalidPrecision},
1739     {"NaN", EXACT, "NaN", Success},
1740     {"NaN", 0, "NaN", InvalidPrecision},
1741     {"NaN", 1, "NaN", Success},
1742     {"NaN", 15, "NaN", Success},
1743     {"NaN", 16, "NaN", InvalidPrecision},
1744     {"0", -10, "NaN", InvalidPrecision},
1745     {"0", EXACT, "0", Success},
1746     {"0", 0, "NaN", InvalidPrecision},
1747     {"0", 1, "0", Success},
1748     {"0", 15, "0", Success},
1749     {"0", 16, "NaN", InvalidPrecision},
1750     {"12305", EXACT, "1.2305e4", Success},
1751     {"12305", -1, "NaN", InvalidPrecision},
1752     {"12305", 0, "NaN", InvalidPrecision},
1753     {"12305", 1, "1.e4", Success},
1754     {"12305", 2, "1.2e4", Success},
1755     {"12305", 3, "1.23e4", Success},
1756     {"12305", 4, "1.23e4", Success},
1757     {"12305", 5, "1.2305e4", Success},
1758     {"12305", 6, "1.2305e4", Success},
1759     {"-12305", 5, "-1.2305e4", Success},
1760     {"1.234567890123456789", 0, "NaN", InvalidPrecision},
1761     {"1.234567890123456789", 1, "1.e0", Success},
1762     {"1.234567890123456789", 14, "1.2345678901234e0", Success},
1763     {"1.234567890123456789", 15, "1.23456789012345e0", Success},
1764     {"1.23456789012345006789", 16, "NaN", InvalidPrecision},
1765     {"1.23456789012345006789", EXACT, "NaN", InvalidPrecision},
1766   };
1767 
1768   printf("testing float_copy\n");
1769 
1770   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1771     if(!tc_copy(testcases[i].src, testcases[i].digits, testcases[i].error,
1772                 testcases[i].result))
1773       return tc_fail(i);
1774   return 1;
1775 }
1776 
tc_move(const char * value)1777 static int tc_move(const char* value)
1778 {
1779   floatstruct f, g;
1780   int save, refs, code;
1781   char retvalue;
1782   char buf[50];
1783 
1784   float_create(&f);
1785   refs = _one_->n_refs;
1786   g.significand = bc_copy_num(_one_);
1787   g.exponent = 12;
1788   save = float_setprecision(50);
1789   float_setasciiz(&f, value);
1790   float_setprecision(save);
1791   float_geterror();
1792   float_move(&g, &f);
1793   code = float_geterror();
1794   float_getscientific(buf, sizeof(buf), &g);
1795   retvalue = refs == _one_->n_refs
1796              && float_isnan(&f)
1797              && strcmp(buf, value) == 0
1798              && code == Success;
1799   float_free(&g);
1800   return retvalue;
1801 }
1802 
test_move()1803 static int test_move()
1804 {
1805   int i;
1806   static struct{
1807     const char* value;
1808   } testcases[] = {
1809     {"NaN"},
1810     {"0"},
1811     {"1.e0"},
1812     {"1.e-1"},
1813     {"1.e1"},
1814     {"-1.e1"},
1815     {"1.234567890123456789e0"},
1816   };
1817 
1818   printf("testing float_move\n");
1819 
1820   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1821     if(!tc_move(testcases[i].value))
1822       return tc_fail(i);
1823   return 1;
1824 }
1825 
tc_round(const char * value,int digits,const char * up,const char * down,int roundflags,Error error)1826 static int tc_round(const char* value, int digits, const char* up,
1827                     const char* down, int roundflags, Error error)
1828 {
1829   floatstruct f, g;
1830   Error code;
1831   int flag, refs, save, cmp, cd;
1832   char buf[50];
1833   roundmode rm;
1834   char err;
1835 
1836   float_create(&f);
1837   flag = 1;
1838   refs = _one_->n_refs;
1839   g.significand = bc_copy_num(_one_);
1840   g.exponent = 0;
1841   save = float_setprecision(50);
1842   float_setasciiz(&f, value);
1843   float_setprecision(save);
1844   float_geterror();
1845   err = float_round(&g, &f, digits, 5);
1846   code = float_geterror();
1847   if (err != 0 || code != InvalidParam || !float_isnan(&g)
1848       || refs != _one_->n_refs)
1849     return 0;
1850   for (rm = TONEAREST; rm <= TOMINUSINFINITY; ++rm)
1851   {
1852     refs = _one_->n_refs;
1853     g.significand = bc_copy_num(_one_);
1854     g.exponent = 0;
1855     save = float_setprecision(50);
1856     float_setasciiz(&f, value);
1857     float_setprecision(save);
1858     float_geterror();
1859     err = float_round(&g, &f, digits, rm);
1860     code = float_geterror();
1861     float_getscientific(buf, sizeof(buf), &g);
1862     cd = Success;
1863     if ((flag & roundflags) != 0)
1864     {
1865       if (*up == 'N')
1866         cd = error;
1867       cmp = strcmp(buf, up);
1868     }
1869     else
1870     {
1871       if (*down == 'N')
1872         cd = error;
1873       cmp = strcmp(buf, down);
1874     }
1875     if (cmp != 0
1876         || code != cd
1877         || !logequiv(code, !err))
1878       return 0;
1879     float_geterror();
1880     err = float_round(&f, &f, digits, rm);
1881     code = float_geterror();
1882     float_getscientific(buf, sizeof(buf), &f);
1883     cd = Success;
1884     if ((flag & roundflags) != 0)
1885     {
1886       if (*up == 'N')
1887         cd = error;
1888       cmp = strcmp(buf, up);
1889     }
1890     else
1891     {
1892       if (*down == 'N')
1893         cd = error;
1894       cmp = strcmp(buf, down);
1895     }
1896     if (cmp != 0
1897         || code != cd
1898         || !logequiv(code, !err))
1899       return 0;
1900     flag *=2;
1901   }
1902   float_free(&f);
1903   float_free(&g);
1904   return 1;
1905 }
1906 
1907 #define FN  1
1908 #define FZ  2
1909 #define FI  4
1910 #define FU  8
1911 #define FD 16
1912 
test_round()1913 static int test_round()
1914 {
1915   int i;
1916   static struct{
1917     const char* value; int digits; const char* up; const char* down;
1918     int roundflags; Error error;
1919   } testcases[] = {
1920     {"NaN", -1, "NaN", "NaN", 0, InvalidPrecision},
1921     {"NaN", 0, "NaN", "NaN", 0, InvalidPrecision},
1922     {"NaN", 16, "NaN", "NaN", 0, InvalidPrecision},
1923     {"NaN", 1, "NaN", "NaN", 0, NoOperand},
1924     {"0", -1, "NaN", "NaN", 0, InvalidPrecision},
1925     {"0", 0, "NaN", "NaN", 0, InvalidPrecision},
1926     {"0", 16, "NaN", "NaN", 0, InvalidPrecision},
1927     {"0", 1, "0", "0", 0, Success},
1928     {"1", -1, "NaN", "NaN", 0, InvalidPrecision},
1929     {"1", 0, "NaN", "NaN", 0, InvalidPrecision},
1930     {"1", 16, "NaN", "NaN", 0, InvalidPrecision},
1931     {"1", 1, "1.e0", "1.e0", 0, Success},
1932     {"1", 2, "1.e0", "1.e0", 0, Success},
1933     {"1", 15, "1.e0", "1.e0", 0, Success},
1934     {"-1", -1, "NaN", "NaN", 0, InvalidPrecision},
1935     {"-1", 0, "NaN", "NaN", 0, InvalidPrecision},
1936     {"-1", 16, "NaN", "NaN", 0, InvalidPrecision},
1937     {"-1", 1, "-1.e0", "-1.e0", 0, Success},
1938     {"-1", 2, "-1.e0", "-1.e0", 0, Success},
1939     {"-1", 15, "-1.e0", "-1.e0", 0, Success},
1940     {"1.903", 1, "2.e0", "1.e0", FN+FI+FU, Success},
1941     {"1.903", 2, "2.e0", "1.9e0", FI+FU, Success},
1942     {"1.903", 3, "1.91e0", "1.9e0", FI+FU, Success},
1943     {"1.903", 4, "1.903e0", "1.903e0", 0, Success},
1944     {"1.903", 5, "1.903e0", "1.903e0", 0, Success},
1945     {"19.03", 1, "2.e1", "1.e1", FN+FI+FU, Success},
1946     {"19.03", 2, "2.e1", "1.9e1", FI+FU, Success},
1947     {"19.03", 3, "1.91e1", "1.9e1", FI+FU, Success},
1948     {"19.03", 4, "1.903e1", "1.903e1", 0, Success},
1949     {"19.03", 5, "1.903e1", "1.903e1", 0, Success},
1950     {"0.1903", 1, "2.e-1", "1.e-1", FN+FI+FU, Success},
1951     {"0.1903", 2, "2.e-1", "1.9e-1", FI+FU, Success},
1952     {"0.1903", 3, "1.91e-1", "1.9e-1", FI+FU, Success},
1953     {"0.1903", 4, "1.903e-1", "1.903e-1", 0, Success},
1954     {"0.1903", 5, "1.903e-1", "1.903e-1", 0, Success},
1955     {"-1.903", 1, "-1.e0", "-2.e0", FZ+FU, Success},
1956     {"-1.903", 2, "-1.9e0", "-2.e0", FN+FZ+FU, Success},
1957     {"-1.903", 3, "-1.9e0", "-1.91e0", FN+FZ+FU, Success},
1958     {"-1.903", 4, "-1.903e0", "-1.903e0", 0, Success},
1959     {"-1.903", 5, "-1.903e0", "-1.903e0", 0, Success},
1960     {"1.29903", 1, "2.e0", "1.e0", FI+FU, Success},
1961     {"1.29903", 2, "1.3e0", "1.2e0", FN+FI+FU, Success},
1962     {"1.29903", 3, "1.3e0", "1.29e0", FN+FI+FU, Success},
1963     {"1.29903", 4, "1.3e0", "1.299e0", FI+FU, Success},
1964     {"1.29903", 5, "1.2991e0", "1.299e0", FI+FU, Success},
1965     {"1.29903", 6, "1.29903e0", "1.29903e0", 0, Success},
1966     {"9.99", 1, "1.e1", "9.e0", FN+FI+FU, Success},
1967     {"9.99", 2, "1.e1", "9.9e0", FN+FI+FU, Success},
1968     {"9.99", 3, "9.99e0", "9.99e0", 0, Success},
1969     {"1.5", 1, "2.e0", "1.e0", FN+FI+FU, Success},
1970     {"2.5", 1, "3.e0", "2.e0", FI+FU, Success},
1971     {"9.99e100", 1, "NaN", "9.e100", FN+FI+FU, Overflow},
1972     {"9.99e100", 2, "NaN", "9.9e100", FN+FI+FU, Overflow},
1973     {"9.99e100", 3, "9.99e100", "9.99e100", 0, Success},
1974     {"9.995e100", 3, "NaN", "9.99e100", FN+FI+FU, Overflow},
1975   };
1976   int save;
1977 
1978   printf("testing float_round\n");
1979 
1980   save = float_setrange(100);
1981   for(i = -1; ++i < sizeof(testcases)/sizeof(testcases[0]);)
1982     if(!tc_round(testcases[i].value, testcases[i].digits, testcases[i].up,
1983         testcases[i].down, testcases[i].roundflags, testcases[i].error))
1984       return tc_fail(i);
1985   float_setrange(save);
1986   return 1;
1987 }
1988 
tc_add(char * msg,char * val1,char * val2,int digits,char * result)1989 static int tc_add(char* msg, char* val1, char* val2, int digits, char* result)
1990 {
1991   floatstruct v1;
1992   floatstruct v2;
1993   floatstruct b1;
1994   floatstruct b2;
1995   floatstruct sum;
1996   int lg;
1997   char ok;
1998   char buf[30];
1999 
2000   float_create(&v1);
2001   float_create(&v2);
2002   float_create(&b1);
2003   float_create(&b2);
2004   float_create(&sum);
2005 
2006   printf("%s", msg);
2007   float_setscientific(&v1, val1, NULLTERMINATED);
2008   float_setscientific(&v2, val2, NULLTERMINATED);
2009   float_copy(&b1, &v1, EXACT);
2010   float_copy(&b2, &v2, EXACT);
2011   float_add(&sum, &v1, &v2, digits);
2012 
2013   float_getscientific(buf, 30, &sum);
2014   lg = strlen(result);
2015   ok = _cmp(&v1, &b1) == 0
2016        && _cmp(&v2, &b2) == 0
2017        && lg == strlen(buf)
2018        && memcmp(buf, result, lg) == 0? TRUE : FALSE;
2019 
2020   float_free(&v1);
2021   float_free(&v2);
2022   float_free(&b1);
2023   float_free(&b2);
2024   float_free(&sum);
2025 
2026   return ok;
2027 }
2028 
test_add()2029 static int test_add()
2030 {
2031   floatstruct v1;
2032   floatstruct v2;
2033   floatstruct save;
2034   char nmb[30];
2035   char nmb2[30];
2036 
2037   printf("\ntesting float_add\n");
2038   float_create(&v1);
2039   float_create(&v2);
2040   float_create(&save);
2041   maxexp(nmb, "+9.9e");
2042 
2043   if (!tc_add("invalid length\n", "0", "0", 0, "NaN")) return FALSE;
2044   if (!tc_add("NaN, both op\n", "NaN", "NaN", 3, "NaN")) return FALSE;
2045   if (!tc_add("NaN, first op\n", "NaN", "0", 3, "NaN")) return FALSE;
2046   if (!tc_add("NaN, second op\n", "0", "NaN", 3, "NaN")) return FALSE;
2047   if (!tc_add("0 + 0\n", "0", "0", 3, "0")) return FALSE;
2048   if (!tc_add("0 + 1\n", "0", "1", 3, "1.e0")) return FALSE;
2049   if (!tc_add("1 + 0\n", "1", "0", 3, "1.e0")) return FALSE;
2050   if (!tc_add("1 + 1\n", "1", "1", EXACT, "2.e0")) return FALSE;
2051   if (!tc_add("1 + 0.1\n", "1", "0.1", EXACT, "1.1e0")) return FALSE;
2052   if (!tc_add("0.1 + 1\n", "0.1", "1", EXACT, "1.1e0")) return FALSE;
2053   if (!tc_add("scale overflow, 1E-20 + 1\n", "1.E-20", "1", EXACT, "NaN")) return FALSE;
2054   if (!tc_add("1E-20 + 1\n", "1.E-20", "1", 10, "1.e0")) return FALSE;
2055   if (!tc_add("1.234 + 0.1\n", "1.234", "0.1", EXACT, "1.334e0")) return FALSE;
2056   if (!tc_add("1.234 + 0.12345\n", "1.234", "0.12345", EXACT, "1.35745e0")) return FALSE;
2057   if (!tc_add("1.234 + 0.12345, lg 5\n", "1.234", "0.12345", 5, "1.3574e0")) return FALSE;
2058   if (!tc_add("1.234 + 0.12345, lg 4\n", "1.234", "0.12345", 4, "1.357e0")) return FALSE;
2059   if (!tc_add("1.234 + 0.12345, lg 3\n", "1.234", "0.12345", 3, "1.35e0")) return FALSE;
2060   if (!tc_add("1.234 + 0.12345, lg 2\n", "1.234", "0.12345", 2, "1.3e0")) return FALSE;
2061   if (!tc_add("1.234 + 0.12345, lg 1\n", "1.234", "0.12345", 1, "1.e0")) return FALSE;
2062   if (!tc_add("123.001 + (-122.85)\n", "123.001", "-122.85", 1, "2.e-1")) return FALSE;
2063   if (!tc_add("123.0014 + (-122.954)\n", "123.0014", "-122.954", 1, "5.e-2")) return FALSE;
2064   if (!tc_add("123.0014 + (-122.9954)\n", "123.0014", "-122.9954", 1, "6.e-3")) return FALSE;
2065   if (!tc_add("123 + (-122.9954)\n", "123", "-122.9954", 1, "5.e-3")) return FALSE;
2066   if (!tc_add("2 + (-1.9954)\n", "2", "-1.9954", 1, "5.e-3")) return FALSE;
2067   if (!tc_add("(-1.9954) + 2\n", "-1.9954", "2", 1, "5.e-3")) return FALSE;
2068   if (!tc_add("1 + (-0.9954)\n", "1", "-0.9954", 1, "5.e-3")) return FALSE;
2069   if (!tc_add("1.00001 + (-0.9954)\n", "1.00001", "-0.9954", 1, "5.e-3")) return FALSE;
2070   if (!tc_add("1.00001 + (-0.99)\n", "1.00001", "-0.99", 1, "1.e-2")) return FALSE;
2071   if (!tc_add("1.00001 + (-0.9999999)\n", "1.00001", "-0.9999999", 1, "2.e-5")) return FALSE;
2072   if (!tc_add("max + 1E-10000\n", nmb, "1E-10000", 2, nmb+1)) return FALSE;
2073   if (!tc_add("overflow\n", nmb, nmb, 2, "NaN")) return FALSE;
2074   if (!tc_add("2 + (-1)\n", "2", "-1", 2, "1.e0")) return FALSE;
2075   if (!tc_add("(-1) + 2\n", "-1", "2", 2, "1.e0")) return FALSE;
2076   if (!tc_add("2 + (-0.1)\n", "2", "-0.1", EXACT, "1.9e0")) return FALSE;
2077   if (!tc_add("1 + (-0.1)\n", "1", "-0.1", EXACT, "9.e-1")) return FALSE;
2078   if (!tc_add("1 + (-0.1), lg 1\n", "1", "-0.1", 1, "9.e-1")) return FALSE;
2079   if (!tc_add("123 + (-100)\n", "123", "-100", EXACT, "2.3e1")) return FALSE;
2080   if (!tc_add("(-123) + 100\n", "-123", "100", EXACT, "-2.3e1")) return FALSE;
2081   if (!tc_add("123 + (-120)\n", "123", "-120", EXACT, "3.e0")) return FALSE;
2082   if (!tc_add("123 + (-124)\n", "123", "-124", EXACT, "-1.e0")) return FALSE;
2083   if (!tc_add("123 + (-123)\n", "123", "-123", EXACT, "0")) return FALSE;
2084   if (!tc_add("123.04 + (-123)\n", "123.04", "-123", EXACT, "4.e-2")) return FALSE;
2085   if (!tc_add("123.04 + (-123)\n", "123.04", "-123", 1, "4.e-2")) return FALSE;
2086   if (!tc_add("123.24 + (-123.11)\n", "123.24", "-123.11", 1, "1.3e-1")) return FALSE;
2087   if (!tc_add("123.046 + (-123.115)\n", "123.046", "-123.115", 1, "-7.e-2")) return FALSE;
2088   if (!tc_add("123 + (-120), lg 1\n", "123", "-120", 1, "3.e0")) return FALSE;
2089   if (!tc_add("underflow\n", minexp(nmb, "1.1e"), minexp(nmb2, "-1e"), 5, "NaN")) return FALSE;
2090   if (!tc_add("underflow due to borrow\n", minexp(nmb, "2.0001e"), minexp(nmb2, "-1.99955e"), 5, "NaN")) return FALSE;
2091   if (!tc_add("underflow due to cancel\n", minexp(nmb, "1.234e"), minexp(nmb2, "-1.231e"), 5, "NaN")) return FALSE;
2092   printf("%s\n", "in place add, first");
2093   float_setscientific(&v1, "120", NULLTERMINATED);
2094   float_setscientific(&v2, "-3.4e-1", NULLTERMINATED);
2095   float_copy(&save, &v2, EXACT);
2096   float_add(&v1, &v1, &v2, EXACT);
2097   float_getscientific(nmb, 30, &v1);
2098   if (memcmp("1.1966e2", nmb, 9) != 0 || _cmp(&v2, &save) != 0) return FALSE;
2099   printf("%s\n", "in place add, second");
2100   float_copy(&save, &v1, EXACT);
2101   float_add(&v2, &v1, &v2, EXACT);
2102   float_getscientific(nmb, 30, &v2);
2103   if (memcmp("1.1932e2", nmb, 9) != 0 || _cmp(&v1, &save) != 0) return FALSE;
2104   printf("%s\n", "in place add, both");
2105   float_add(&v2, &v2, &v2, EXACT);
2106   float_getscientific(nmb, 30, &v2);
2107   if (memcmp("2.3864e2", nmb, 9) != 0) return FALSE;
2108 
2109   float_free(&v1);
2110   float_free(&v2);
2111   float_free(&save);
2112   return TRUE;
2113 }
2114 
tc_sub(char * msg,char * val1,char * val2,int digits,char * result)2115 static int tc_sub(char* msg, char* val1, char* val2, int digits, char* result)
2116 {
2117   floatstruct v1;
2118   floatstruct v2;
2119   floatstruct b1;
2120   floatstruct b2;
2121   floatstruct diff;
2122   int lg;
2123   char ok;
2124   char buf[30];
2125 
2126   float_create(&v1);
2127   float_create(&v2);
2128   float_create(&b1);
2129   float_create(&b2);
2130   float_create(&diff);
2131 
2132   printf("%s", msg);
2133   float_setscientific(&v1, val1, NULLTERMINATED);
2134   float_setscientific(&v2, val2, NULLTERMINATED);
2135   float_copy(&b1, &v1, EXACT);
2136   float_copy(&b2, &v2, EXACT);
2137   float_sub(&diff, &v1, &v2, digits);
2138 
2139   float_getscientific(buf, 30, &diff);
2140   lg = strlen(result);
2141   ok = _cmp(&v1, &b1) == 0
2142        && _cmp(&v2, &b2) == 0
2143        && lg == strlen(buf)
2144        && memcmp(buf, result, lg) == 0? TRUE : FALSE;
2145 
2146   float_free(&v1);
2147   float_free(&v2);
2148   float_free(&b1);
2149   float_free(&b2);
2150   float_free(&diff);
2151 
2152   return ok;
2153 }
2154 
test_sub()2155 static int test_sub()
2156 {
2157   floatstruct v1;
2158   floatstruct v2;
2159   floatstruct save;
2160   char nmb[30];
2161 
2162   printf("\ntesting float_sub\n");
2163   float_create(&v1);
2164   float_create(&v2);
2165   float_create(&save);
2166   if (!tc_sub("invalid length\n", "0", "0", 0, "NaN")) return FALSE;
2167   if (!tc_sub("NaN, both op\n", "NaN", "NaN", 3, "NaN")) return FALSE;
2168   if (!tc_sub("NaN, first op\n", "NaN", "0", 3, "NaN")) return FALSE;
2169   if (!tc_sub("NaN, second op\n", "0", "NaN", 3, "NaN")) return FALSE;
2170   if (!tc_sub("0 - 0\n", "0", "0", 3, "0")) return FALSE;
2171   if (!tc_sub("0 - 1\n", "0", "1", 3, "-1.e0")) return FALSE;
2172   if (!tc_sub("1 - 0\n", "1", "0", 3, "1.e0")) return FALSE;
2173   if (!tc_sub("1 - 1\n", "1", "1", EXACT, "0")) return FALSE;
2174   if (!tc_sub("1 - 0.1\n", "1", "0.1", EXACT, "9.e-1")) return FALSE;
2175   if (!tc_sub("0.1 - 1\n", "0.1", "1", EXACT, "-9.e-1")) return FALSE;
2176   printf("%s\n", "in place sub, first");
2177   float_setscientific(&v1, "120", NULLTERMINATED);
2178   float_setscientific(&v2, "-3.4e-1", NULLTERMINATED);
2179   float_copy(&save, &v2, EXACT);
2180   float_sub(&v1, &v1, &v2, EXACT);
2181   float_getscientific(nmb, 30, &v1);
2182   if (memcmp("1.2034e2", nmb, 9) != 0 || _cmp(&v2, &save) != 0) return FALSE;
2183   printf("%s\n", "in place sub, second");
2184   float_copy(&save, &v1, EXACT);
2185   float_sub(&v2, &v1, &v2, EXACT);
2186   float_getscientific(nmb, 30, &v2);
2187   if (memcmp("1.2068e2", nmb, 9) != 0 || _cmp(&v1, &save) != 0) return FALSE;
2188   printf("%s\n", "in place sub, both");
2189   float_sub(&v2, &v2, &v2, EXACT);
2190   if (!float_iszero(&v2)) return FALSE;
2191   float_free(&v1);
2192   float_free(&v2);
2193   float_free(&save);
2194   return TRUE;
2195 }
2196 
tc_mul(char * msg,char * val1,char * val2,int digits,char * result)2197 static int tc_mul(char* msg, char* val1, char* val2, int digits, char* result)
2198 {
2199  floatstruct v1;
2200   floatstruct v2;
2201   floatstruct b1;
2202   floatstruct b2;
2203   floatstruct prod;
2204   int lg;
2205   char ok;
2206   char buf[30];
2207 
2208   float_create(&v1);
2209   float_create(&v2);
2210   float_create(&b1);
2211   float_create(&b2);
2212   float_create(&prod);
2213 
2214   printf("%s", msg);
2215   float_setscientific(&v1, val1, NULLTERMINATED);
2216   float_setscientific(&v2, val2, NULLTERMINATED);
2217   float_copy(&b1, &v1, EXACT);
2218   float_copy(&b2, &v2, EXACT);
2219   float_mul(&prod, &v1, &v2, digits);
2220 
2221   float_getscientific(buf, 30, &prod);
2222   lg = strlen(result);
2223   ok = _cmp(&v1, &b1) == 0
2224        && _cmp(&v2, &b2) == 0
2225        && lg == strlen(buf)
2226        && memcmp(buf, result, lg) == 0? TRUE : FALSE;
2227 
2228   float_free(&v1);
2229   float_free(&v2);
2230   float_free(&b1);
2231   float_free(&b2);
2232   float_free(&prod);
2233 
2234   return ok;
2235 }
2236 
test_mul()2237 static int test_mul()
2238 {
2239   floatstruct v1;
2240   floatstruct v2;
2241   floatstruct save;
2242   char nmb[30];
2243   char nmb2[30];
2244 
2245   printf("\ntesting float_mul\n");
2246   float_create(&v1);
2247   float_create(&v2);
2248   float_create(&save);
2249 
2250   if (!tc_mul("invalid length\n", "0", "0", 0, "NaN")) return FALSE;
2251   if (!tc_mul("NaN, both op\n", "NaN", "NaN", 3, "NaN")) return FALSE;
2252   if (!tc_mul("NaN, first op\n", "NaN", "0", 3, "NaN")) return FALSE;
2253   if (!tc_mul("NaN, second op\n", "0", "NaN", 3, "NaN")) return FALSE;
2254   if (!tc_mul("0 * 0\n", "0", "0", 3, "0")) return FALSE;
2255   if (!tc_mul("0 * 1\n", "0", "1", 3, "0")) return FALSE;
2256   if (!tc_mul("1 * 0\n", "1", "0", 3, "0")) return FALSE;
2257   if (!tc_mul("1 * 1\n", "1", "1", EXACT, "1.e0")) return FALSE;
2258   if (!tc_mul("1 * -1\n", "1", "-1", EXACT, "-1.e0")) return FALSE;
2259   if (!tc_mul("-1 * 1\n", "-1", "1", EXACT, "-1.e0")) return FALSE;
2260   if (!tc_mul("-1 * -1\n", "-1", "-1", EXACT, "1.e0")) return FALSE;
2261   if (!tc_mul("2 * 3\n", "2", "3", EXACT, "6.e0")) return FALSE;
2262   if (!tc_mul("3 * 4\n", "3", "4", EXACT, "1.2e1")) return FALSE;
2263   if (!tc_mul("123 * 456\n", "123", "456", EXACT, "5.6088e4")) return FALSE;
2264   if (!tc_mul("3E100 * 4E-100\n", "3E100", "4E-100", EXACT, "1.2e1")) return FALSE;
2265   if (!tc_mul("big exp diff\n", maxexp(nmb, "5e"), minexp(nmb2, "2e"), EXACT, "1.e0")) return FALSE;
2266   if (!tc_mul("almost overflow\n", maxexp(nmb, "4.9e"), "2", EXACT, maxexp(nmb2, "9.8e"))) return FALSE;
2267   if (!tc_mul("overflow\n", maxexp(nmb, "5e"), "2", EXACT, "NaN")) return FALSE;
2268   if (!tc_mul("big overflow\n", maxexp(nmb, "5e"), nmb, EXACT, "NaN")) return FALSE;
2269   if (!tc_mul("almost underflow\n", minexp(nmb, "5e"), "0.2", EXACT, minexp(nmb2, "1.e"))) return FALSE;
2270   if (!tc_mul("underflow\n", minexp(nmb, "4e"), "0.2", EXACT, "NaN")) return FALSE;
2271   if (!tc_mul("big underflow\n", minexp(nmb, "1e"), nmb, EXACT, "NaN")) return FALSE;
2272   if (!tc_mul("scale overflow\n", "1.2345678901", "1.2345678901", EXACT, "NaN")) return FALSE;
2273   printf("%s\n", "in place mul, first");
2274   float_setscientific(&v1, "2", NULLTERMINATED);
2275   float_setscientific(&v2, "-3", NULLTERMINATED);
2276   float_copy(&save, &v2, EXACT);
2277   float_mul(&v1, &v1, &v2, EXACT);
2278   float_getscientific(nmb, 30, &v1);
2279   if (memcmp("-6.e0", nmb, 6) != 0 || _cmp(&v2, &save) != 0) return FALSE;
2280   printf("%s\n", "in place mul, second");
2281   float_copy(&save, &v1, EXACT);
2282   float_mul(&v2, &v1, &v2, EXACT);
2283   float_getscientific(nmb, 30, &v2);
2284   if (memcmp("1.8e1", nmb, 6) != 0 || _cmp(&v1, &save) != 0) return FALSE;
2285   printf("%s\n", "in place mul, both");
2286   float_mul(&v2, &v2, &v2, EXACT);
2287   float_getscientific(nmb, 30, &v2);
2288   if (memcmp("3.24e2", nmb, 7) != 0) return FALSE;
2289   float_free(&v1);
2290   float_free(&v2);
2291   float_free(&save);
2292   return TRUE;
2293 }
2294 
tc_div(char * msg,char * val1,char * val2,int digits,char * result)2295 static int tc_div(char* msg, char* val1, char* val2, int digits, char* result)
2296 {
2297  floatstruct v1;
2298   floatstruct v2;
2299   floatstruct b1;
2300   floatstruct b2;
2301   floatstruct quot;
2302   int lg;
2303   char ok;
2304   char buf[30];
2305 
2306   float_create(&v1);
2307   float_create(&v2);
2308   float_create(&b1);
2309   float_create(&b2);
2310   float_create(&quot);
2311 
2312   printf("%s", msg);
2313   float_setscientific(&quot, "1.823452", NULLTERMINATED);
2314   float_setscientific(&v1, val1, NULLTERMINATED);
2315   float_setscientific(&v2, val2, NULLTERMINATED);
2316   float_copy(&b1, &v1, EXACT);
2317   float_copy(&b2, &v2, EXACT);
2318   float_div(&quot, &v1, &v2, digits);
2319 
2320   float_getscientific(buf, 30, &quot);
2321   lg = strlen(result);
2322   ok = _cmp(&v1, &b1) == 0
2323        && _cmp(&v2, &b2) == 0
2324        && lg == strlen(buf)
2325        && memcmp(buf, result, lg) == 0? TRUE : FALSE;
2326 
2327   float_free(&v1);
2328   float_free(&v2);
2329   float_free(&b1);
2330   float_free(&b2);
2331   float_free(&quot);
2332 
2333   return ok;
2334 }
2335 
test_div()2336 static int test_div()
2337 {
2338   floatstruct v1;
2339   floatstruct v2;
2340   floatstruct save;
2341   char nmb[30];
2342   char nmb2[30];
2343 
2344   printf("\ntesting float_div\n");
2345   float_create(&v1);
2346   float_create(&v2);
2347   float_create(&save);
2348 
2349   if(!tc_div("invalid digits\n", "1", "1", EXACT, "NaN")) return FALSE;
2350   if(!tc_div("NaN, both\n", "NaN", "NaN", 5, "NaN")) return FALSE;
2351   if(!tc_div("NaN, first\n", "NaN", "1", 5, "NaN")) return FALSE;
2352   if(!tc_div("NaN, second\n", "1", "NaN", 5, "NaN")) return FALSE;
2353   if(!tc_div("0/1\n", "0", "1", 5, "0")) return FALSE;
2354   if(!tc_div("1/0\n", "1", "0", 5, "NaN")) return FALSE;
2355   if(!tc_div("0/0\n", "0", "0", 5, "NaN")) return FALSE;
2356   if(!tc_div("1/1\n", "1", "1", 5, "1.e0")) return FALSE;
2357   if(!tc_div("(-1)/1\n", "-1", "1", 5, "-1.e0")) return FALSE;
2358   if(!tc_div("1/(-1)\n", "1", "-1", 5, "-1.e0")) return FALSE;
2359   if(!tc_div("(-1)/(-1)\n", "-1", "-1", 5, "1.e0")) return FALSE;
2360   if(!tc_div("1/2\n", "1", "2", 5, "5.e-1")) return FALSE;
2361   if(!tc_div("1/3\n", "1", "3", 5, "3.3333e-1")) return FALSE;
2362   if(!tc_div("4/3\n", "4", "3", 5, "1.33333e0")) return FALSE;
2363   if(!tc_div("40/0.3\n", "40", "0.3", 5, "1.33333e2")) return FALSE;
2364   if(!tc_div("0.4/0.03\n", "0.4", "0.03", 5, "1.33333e1")) return FALSE;
2365   if(!tc_div("400/30\n", "400", "30", 5, "1.33333e1")) return FALSE;
2366   if(!tc_div("400/30000\n", "400", "30000", 5, "1.33333e-2")) return FALSE;
2367   if(!tc_div("0.0004/0.3\n", "0.0004", "0.3", 5, "1.33333e-3")) return FALSE;
2368   if(!tc_div("integer quotient, 1/3\n", "1", "3", INTQUOT, "0")) return FALSE;
2369   if(!tc_div("integer quotient, 4/3\n", "4", "3", INTQUOT, "1.e0")) return FALSE;
2370   if(!tc_div("integer quotient, 4/3\n", "4", "3", INTQUOT, "1.e0")) return FALSE;
2371   if(!tc_div("integer quotient, 4/3\n", "4", "0.3", INTQUOT, "1.3e1")) return FALSE;
2372   if(!tc_div("integer quotient, 1/3\n", "1", "0.3", INTQUOT, "3.e0")) return FALSE;
2373   if(!tc_div("integer quotient, 1/30\n", "1", "30", INTQUOT, "0")) return FALSE;
2374   if(!tc_div("almost overflow\n", maxexp(nmb, "1.e"), "0.3", 5, maxexp(nmb2, "3.3333e"))) return FALSE;
2375   if(!tc_div("overflow\n", maxexp(nmb, "4.e"), "0.3", 5, "NaN")) return FALSE;
2376   if(!tc_div("big overflow\n", maxexp(nmb, "4.e"), minexp(nmb2, "1.e"), 5, "NaN")) return FALSE;
2377   if(!tc_div("almost underflow\n", minexp(nmb, "4.e"), "3", 5, minexp(nmb2, "1.33333e"))) return FALSE;
2378   if(!tc_div("underflow\n", minexp(nmb, "1.e"), "3", 5, "NaN")) return FALSE;
2379   if(!tc_div("big underflow\n", minexp(nmb, "1.e"), maxexp(nmb2, "1.e"), 5, "NaN")) return FALSE;
2380   if(!tc_div("scale overflow\n", "1", "2", 20, "NaN")) return FALSE;
2381   printf("%s\n", "in place div, first");
2382   float_setscientific(&v1, "1", NULLTERMINATED);
2383   float_setscientific(&v2, "-2", NULLTERMINATED);
2384   float_copy(&save, &v2, EXACT);
2385   float_div(&v1, &v1, &v2, 5);
2386   float_getscientific(nmb, 30, &v1);
2387   if (memcmp("-5.e-1", nmb, 7) != 0 || _cmp(&v2, &save) != 0) return FALSE;
2388   printf("%s\n", "in place div, second");
2389   float_copy(&save, &v1, EXACT);
2390   float_div(&v2, &v1, &v2, 5);
2391   float_getscientific(nmb, 30, &v2);
2392   if (memcmp("2.5e-1", nmb, 7) != 0 || _cmp(&v1, &save) != 0) return FALSE;
2393   printf("%s\n", "in place div, both");
2394   float_div(&v2, &v2, &v2, 5);
2395   float_getscientific(nmb, 30, &v2);
2396   if (memcmp("1.e0", nmb, 5) != 0) return FALSE;
2397   float_free(&v1);
2398   float_free(&v2);
2399   float_free(&save);
2400   return TRUE;
2401 }
2402 
tc_sqrt(char * msg,char * val,int digits,char * result)2403 static int tc_sqrt(char* msg, char* val, int digits, char* result)
2404 {
2405   floatstruct v;
2406   int lg;
2407   char buf[30];
2408 
2409   printf("%s", msg);
2410   float_create(&v);
2411   float_setscientific(&v, val, NULLTERMINATED);
2412   float_sqrt(&v, digits);
2413   float_round(&v, &v, digits - 1, TONEAREST);
2414   float_getscientific(buf, 30, &v);
2415   float_free(&v);
2416   lg = strlen(result);
2417   return strlen(buf) == lg && memcmp(buf, result, lg) == 0? TRUE : FALSE;
2418 }
2419 
test_sqrt()2420 static int test_sqrt()
2421 {
2422   printf("\ntesting float_sqrt\n");
2423 
2424   if (!tc_sqrt("invalid length\n", "1", 0, "NaN")) return FALSE;
2425   if (!tc_sqrt("NaN\n", "NaN", 5, "NaN")) return FALSE;
2426   if (!tc_sqrt("negative value\n", "-1", 5, "NaN")) return FALSE;
2427   if (!tc_sqrt("0\n", "0", 5, "0")) return FALSE;
2428   if (!tc_sqrt("1\n", "1", 5, "1.e0")) return FALSE;
2429   if (!tc_sqrt("4\n", "4", 5, "2.e0")) return FALSE;
2430   if (!tc_sqrt("16\n", "16", 5, "4.e0")) return FALSE;
2431   if (!tc_sqrt("0.64\n", "0.64", 5, "8.e-1")) return FALSE;
2432   if (!tc_sqrt("0.04\n", "0.04", 5, "2.e-1")) return FALSE;
2433   return TRUE;
2434 }
2435 
tc_int(char * msg,char * value,char * result)2436 static int tc_int(char* msg, char* value, char* result)
2437 {
2438   floatstruct f;
2439   int lg;
2440   char buf[30];
2441 
2442   printf("%s", msg);
2443   float_create(&f);
2444   float_setscientific(&f, value, NULLTERMINATED);
2445   float_int(&f);
2446   float_getscientific(buf, 30, &f);
2447   lg = strlen(result);
2448   float_free(&f);
2449   return (lg == strlen(buf) && memcmp(buf, result, lg) == 0);
2450 }
2451 
test_int()2452 static int test_int()
2453 {
2454   printf("\ntesting float_int\n");
2455   if (!tc_int("NaN\n", "NaN", "NaN")) return FALSE;
2456   if (!tc_int("0\n", "0", "0")) return FALSE;
2457   if (!tc_int("1\n", "1", "1.e0")) return FALSE;
2458   if (!tc_int("10\n", "10", "1.e1")) return FALSE;
2459   if (!tc_int("10.1\n", "10.1", "1.e1")) return FALSE;
2460   if (!tc_int("0.1\n", "0.1", "0")) return FALSE;
2461   if (!tc_int("-1\n", "-1", "-1.e0")) return FALSE;
2462   if (!tc_int("-10\n", "-10", "-1.e1")) return FALSE;
2463   if (!tc_int("-10.1\n", "-10.1", "-1.e1")) return FALSE;
2464   if (!tc_int("-0.1\n", "-0.1", "0")) return FALSE;
2465   return TRUE;
2466 }
2467 
tc_frac(char * msg,char * value)2468 static int tc_frac(char* msg, char* value)
2469 {
2470   floatstruct f, r;
2471 
2472   printf("%s", msg);
2473   float_create(&f);
2474   float_create(&r);
2475   float_setscientific(&f, value, NULLTERMINATED);
2476   float_copy(&r, &f, EXACT);
2477   float_int(&r);
2478   float_sub(&r, &f, &r, EXACT);
2479   float_frac(&f);
2480   return _cmp(&f, &r) == 0;
2481 }
2482 
test_frac()2483 static int test_frac()
2484 {
2485   printf("\ntesting float_frac\n");
2486   if (!tc_frac("NaN\n", "NaN")) return FALSE;
2487   if (!tc_frac("0\n", "0")) return FALSE;
2488   if (!tc_frac("1\n", "1")) return FALSE;
2489   if (!tc_frac("10\n", "10")) return FALSE;
2490   if (!tc_frac("10.1\n", "10.1")) return FALSE;
2491   if (!tc_frac("0.1\n", "0.1")) return FALSE;
2492   if (!tc_frac("-1\n", "-1")) return FALSE;
2493   if (!tc_frac("-10\n", "-10")) return FALSE;
2494   if (!tc_frac("-10.1\n", "-10.1")) return FALSE;
2495   if (!tc_frac("-0.1\n", "-0.1")) return FALSE;
2496   if (!tc_frac("10.000000001\n", ".000000001")) return FALSE;
2497   return TRUE;
2498 }
2499 
tc_divmod(char * msg,char * dvd,char * dvs,int dig,char * q,char * r)2500 static int tc_divmod(char* msg, char* dvd, char* dvs, int dig, char* q, char* r)
2501 {
2502   int result;
2503   floatstruct v1;
2504   floatstruct v2;
2505   floatstruct b1;
2506   floatstruct b2;
2507   floatstruct r1;
2508   floatstruct r2;
2509 
2510   printf("%s", msg);
2511 
2512   float_create(&v1);
2513   float_create(&v2);
2514   float_create(&b1);
2515   float_create(&b2);
2516   float_create(&r1);
2517   float_create(&r2);
2518 
2519   float_setscientific(&r1, "-1.821923", NULLTERMINATED);
2520   float_setscientific(&r2, "-1.821923", NULLTERMINATED);
2521   float_setscientific(&v1, dvd, NULLTERMINATED);
2522   float_setscientific(&v2, dvs, NULLTERMINATED);
2523 
2524   float_copy(&b1, &v1, EXACT);
2525   float_copy(&b2, &v2, EXACT);
2526 
2527   float_divmod(&r1, &r2, &v1, &v2, dig);
2528 
2529   result = (scmp(&r1, q) && scmp(&r2, r) && _cmp(&v1, &b1) == 0 && _cmp(&v2, &b2) == 0);
2530 
2531   float_free(&v1);
2532   float_free(&v2);
2533   float_free(&b1);
2534   float_free(&b2);
2535   float_free(&r1);
2536   float_free(&r2);
2537   return result;
2538 }
2539 
test_divmod()2540 static int test_divmod()
2541 {
2542   floatstruct f1;
2543   floatstruct f2;
2544   floatstruct f3;
2545   floatstruct vlg;
2546   int save;
2547   char nmb1[30];
2548   char nmb2[30];
2549 
2550   printf("\ntesting float_divmod\n");
2551   float_create(&f1);
2552   float_create(&f2);
2553   float_create(&f3);
2554   float_create(&vlg);
2555 
2556   float_setinteger(&f1, 1);
2557   printf("%s", "test rem == quot\n");
2558   float_divmod(&f1, &f1, &f1, &f1, 5);
2559   if (!float_isnan(&f1)) return FALSE;
2560   if (!tc_divmod("NaN, both\n", "NaN", "NaN", 5, "NaN", "NaN")) return FALSE;
2561   if (!tc_divmod("NaN, 1. op\n", "NaN", "1", 5, "NaN", "NaN")) return FALSE;
2562   if (!tc_divmod("NaN, 2. op\n", "1", "NaN", 5, "NaN", "NaN")) return FALSE;
2563   if (!tc_divmod("invalid digits\n", "1", "1", -5, "NaN", "NaN")) return FALSE;
2564   if (!tc_divmod("test divide by 0\n", "1", "0", 5, "NaN", "NaN")) return FALSE;
2565   if (!tc_divmod("test scale too long\n", "1", "1", 100, "NaN", "NaN")) return FALSE;
2566   if (!tc_divmod("0/1\n", "0", "1", 5, "0", "0")) return FALSE;
2567   if (!tc_divmod("1/100, INTQUOT\n", "1", "100", INTQUOT, "0", "1.e0")) return FALSE;
2568   if (!tc_divmod("INTQUOT, scale too long\n", "1e100", "1", INTQUOT, "NaN", "NaN")) return FALSE;
2569   if (!tc_divmod("1/2, INTQUOT\n", "1", "2", INTQUOT, "0", "1.e0")) return FALSE;
2570   if (!tc_divmod("3/2, INTQUOT\n", "3", "2", INTQUOT, "1.e0", "1.e0")) return FALSE;
2571   if (!tc_divmod("4/2, INTQUOT\n", "4", "2", INTQUOT, "2.e0", "0")) return FALSE;
2572   if (!tc_divmod("213/13, lg 3\n", "213", "13", 3, "1.63e1", "1.1e0")) return FALSE;
2573   if (!tc_divmod("17/16, INTQUOT\n", "17", "16", INTQUOT, "1.e0", "1.e0")) return FALSE;
2574   if (!tc_divmod("1.7/1.6, INTQUOT\n", "1.7", "1.6", INTQUOT, "1.e0", "1.e-1")) return FALSE;
2575   if (!tc_divmod("1.7/1.6, lg 3\n", "1.7", "1.6", 3, "1.06e0", "4.e-3")) return FALSE;
2576   if (!tc_divmod("underflow in quot\n", minexp(nmb1, "1.7e"), "1.6e1", 3, "NaN", "NaN")) return FALSE;
2577   if (!tc_divmod("overflow in quot\n", maxexp(nmb1, "1.7e"), "1.6e-1", 3, "NaN", "NaN")) return FALSE;
2578   if (!tc_divmod("underflow in rem\n", minexp(nmb1, "1.7e"), minexp(nmb2, "1.6e"), INTQUOT, "NaN", "NaN")) return FALSE;
2579   printf("%s", "long divisor\n");
2580   float_setzero(&f1);
2581   float_setzero(&f2);
2582   save = float_setprecision(20);
2583   float_setasciiz(&f3, "12345678901234567890");
2584   float_copy(&vlg, &f3, EXACT);
2585   float_setprecision(save);
2586   float_divmod(&f1, &f2, &f3, &f3, 3);
2587   if (!float_isnan(&f1) || !float_isnan(&f2) || float_cmp(&vlg, &f3) != 0) return FALSE;
2588   printf("%s", "dividend and divisor overwritten by quotient\n");
2589   float_setinteger(&f1, 2);
2590   float_setnan(&f2);
2591   float_divmod(&f1, &f2, &f1, &f1, 3);
2592   if (!scmp(&f1, "1.e0") || !scmp(&f2, "0")) return FALSE;
2593   printf("%s", "dividend and divisor overwritten by remainder\n");
2594   float_setinteger(&f1, 2);
2595   float_setnan(&f2);
2596   float_divmod(&f2, &f1, &f1, &f1, 3);
2597   if (!scmp(&f2, "1.e0") || !scmp(&f1, "0")) return FALSE;
2598   printf("%s", "dividend overwritten by quotient, divisor by remainder\n");
2599   float_setinteger(&f1, 213);
2600   float_setinteger(&f2, 13);
2601   float_divmod(&f1, &f2, &f1, &f2, 3);
2602   if (!scmp(&f1, "1.63e1") || !scmp(&f2, "1.1e0")) return FALSE;
2603   printf("%s", "dividend overwritten by remainder, divisor by quotient\n");
2604   float_setinteger(&f1, 213);
2605   float_setinteger(&f2, 13);
2606   float_divmod(&f2, &f1, &f1, &f2, 3);
2607   if (!scmp(&f2, "1.63e1") || !scmp(&f1, "1.1e0")) return FALSE;
2608   float_free(&f1);
2609   float_free(&f2);
2610   float_free(&f3);
2611   float_free(&vlg);
2612   return TRUE;
2613 }
2614 
_relerror(floatnum x1,floatnum x2)2615 static void _relerror(floatnum x1, floatnum x2)
2616 {
2617   float_sub(x1, x1, x2, 3);
2618   if (!float_iszero(x1))
2619     float_div(x1, x1, x2, 3);
2620   float_abs(x1);
2621 }
2622 
_cmprelerror(floatnum x1,floatnum x2,int exp)2623 static char _cmprelerror(floatnum x1, floatnum x2, int exp)
2624 {
2625   _relerror(x1, x2);
2626   return (float_iszero(x1) || float_getexponent(x1) < exp);
2627 }
2628 
_sub_ulp(floatnum x,int sz)2629 static void _sub_ulp(floatnum x, int sz)
2630 {
2631   floatstruct delta;
2632 
2633   if (!float_iszero(x))
2634   {
2635     float_create(&delta);
2636     float_setinteger(&delta, 1);
2637     float_setexponent(&delta, float_getexponent(x)-sz);
2638     float_setsign(&delta, float_getsign(x));
2639     float_sub(x, x, &delta, EXACT);
2640     float_free(&delta);
2641   }
2642 }
2643 
test_coshminus1near0()2644 static int test_coshminus1near0()
2645 {
2646   floatstruct x, x1, tmp, max;
2647   int i;
2648   char buf[50];
2649 
2650   float_create(&x);
2651   float_create(&x1);
2652   float_create(&tmp);
2653   float_create(&max);
2654   float_setzero(&max);
2655 
2656   printf("%s\n", "testing coshminus1near0");
2657 
2658   printf("verifying special argument x == 0:\n");
2659   float_setzero(&x);
2660   coshminus1near0(&x, 100);
2661   if (!float_iszero(&x))
2662   {
2663     printf("FAILED\n");
2664     return 0;
2665   }
2666 
2667   /* testing the validity of the series evaluation */
2668   printf("verifying result:\n");
2669   float_setasciiz(&x, "0.005");
2670   float_setasciiz(&tmp, ".000012500026041688368065243678286383060391"
2671                         "9872831398280829063464786043942297654015309"
2672                         "5900368700065231210065496027359337789353280"
2673                         "9524874015321513239965");
2674   coshminus1near0(&x, 100);
2675   if (!_cmprelerror(&tmp, &x, -99))
2676   {
2677     printf("FAILED\n");
2678     return 0;
2679   }
2680 
2681   printf("testing error limit:\n");
2682   /* overall scan for maximum relative error */
2683   float_setasciiz(&tmp, ".00001");
2684   for (i = -1; ++i <= 1000;)
2685   {
2686     float_muli(&x, &tmp, i, EXACT);
2687     _sub_ulp(&x, 101);
2688     float_copy(&x1, &x, EXACT);
2689     coshminus1near0(&x,100);
2690     coshminus1near0(&x1, 110);
2691     _relerror(&x1, &x);
2692     if (float_cmp(&x1, &max) > 0)
2693     {
2694       float_copy(&max, &x1, EXACT);
2695       if (float_getexponent(&x1) >= -99)
2696       {
2697         printf("exceeding error for test case %d: ", i);
2698         float_getscientific(buf, 50, &max);
2699         printf("%s\n", buf);
2700         return 0;
2701       }
2702     }
2703   }
2704   float_getscientific(buf, 50, &max);
2705   printf("max error _coshminus1near0: %s\n", buf);
2706 
2707   float_free(&tmp);
2708   float_free(&x);
2709   float_free(&x1);
2710   float_free(&max);
2711   return 1;
2712 }
2713 
test_artanhnear0()2714 static int test_artanhnear0()
2715 {
2716   floatstruct x, x1, tmp, max;
2717   int i;
2718   char buf[50];
2719 
2720   float_create(&x);
2721   float_create(&x1);
2722   float_create(&tmp);
2723   float_create(&max);
2724   float_setzero(&max);
2725 
2726   printf("%s\n", "testing artanhnear0");
2727 
2728   printf("verifying special argument x == 0:\n");
2729   float_setzero(&x);
2730   artanhnear0(&x, 100);
2731   if (!float_iszero(&x))
2732   {
2733     printf("FAILED\n");
2734     return 0;
2735   }
2736 
2737   /* testing correct replacement of artanh by id */
2738 
2739   printf("small x handling:\n");
2740   float_setasciiz(&x, "6.7e-51");
2741   float_copy(&x1, &x, EXACT);
2742   artanhnear0(&x, 100);
2743   artanhnear0(&x1, 110);
2744   if (!_cmprelerror(&x1, &x, -99))
2745   {
2746     printf("FAILED\n");
2747     return 0;
2748   }
2749 
2750   /* testing the validity of the series evaluation */
2751   printf("verifying result:\n");
2752   float_setasciiz(&x, "0.01");
2753   artanhnear0(&x, 100);
2754   float_setasciiz(&x1,".0100003333533347620158821075514042238870"
2755                       "97308807344335621654492648224836625944612"
2756                       "34119694455592889442890269461918262602394"
2757                       "9110421598243");
2758   if (!_cmprelerror(&x1, &x, -99))
2759   {
2760     printf("FAILED\n");
2761     return 0;
2762   }
2763 
2764   printf("testing error limit:\n");
2765   /* overall scan for maximum relative error */
2766   float_setscientific(&tmp, ".0001", NULLTERMINATED);
2767   for (i = -101; ++i <= 100;)
2768   {
2769     float_muli(&x, &tmp, i, EXACT);
2770     _sub_ulp(&x, 101);
2771     float_copy(&x1, &x, EXACT);
2772     artanhnear0(&x,100);
2773     artanhnear0(&x1, 110);
2774     _relerror(&x1, &x);
2775     if (float_cmp(&x1, &max) > 0)
2776     {
2777       float_copy(&max, &x1, EXACT);
2778       if (float_getexponent(&x1) >= -99)
2779       {
2780         printf("exceeding error for test case %d: ", i);
2781         float_getscientific(buf, 50, &max);
2782         printf("%s\n", buf);
2783         return 0;
2784       }
2785     }
2786   }
2787   float_getscientific(buf, 50, &max);
2788   printf("max error artanhnear0: %s\n", buf);
2789   float_free(&tmp);
2790   float_free(&x);
2791   float_free(&x1);
2792   float_free(&max);
2793   return 1;
2794 }
2795 
test_arctannear0()2796 static int test_arctannear0()
2797 {
2798   floatstruct x, x1, tmp, max;
2799   int i;
2800   char buf[50];
2801 
2802   float_create(&x);
2803   float_create(&x1);
2804   float_create(&tmp);
2805   float_create(&max);
2806   float_setzero(&max);
2807 
2808   printf("%s\n", "testing arctannear0");
2809 
2810   printf("verifying special argument x == 0:\n");
2811   float_setzero(&x);
2812   arctannear0(&x, 100);
2813   if (!float_iszero(&x))
2814   {
2815     printf("FAILED\n");
2816     return 0;
2817   }
2818 
2819   /* testing correct replacement of arctan by id */
2820 
2821   printf("small x handling:\n");
2822   float_setasciiz(&x, "6.7e-51");
2823   float_copy(&x1, &x, EXACT);
2824   arctannear0(&x, 100);
2825   arctannear0(&x1, 110);
2826   if (!_cmprelerror(&x1, &x, -99))
2827   {
2828     printf("FAILED\n");
2829     return 0;
2830   }
2831 
2832   /* testing the validity of the series evaluation */
2833   printf("verifying result:\n");
2834   float_setasciiz(&x, "0.01");
2835   arctannear0(&x, 100);
2836   float_setasciiz(&x1,".00999966668666523820634011620927954856136935"
2837                       "254437663962793941819645655320405877997944664"
2838                       "518667409041670798128407565295492085345632123");
2839   if (!_cmprelerror(&x1, &x, -99))
2840   {
2841     printf("FAILED for x == 0.01\n");
2842     return 0;
2843   }
2844 
2845   printf("testing error limit:\n");
2846   /* overall scan for maximum relative error */
2847   float_setscientific(&tmp, ".0001", NULLTERMINATED);
2848   for (i = -101; ++i <= 100;)
2849   {
2850     float_muli(&x, &tmp, i, EXACT);
2851     _sub_ulp(&x, 101);
2852     float_copy(&x1, &x, EXACT);
2853     arctannear0(&x,100);
2854     arctannear0(&x1, 110);
2855     _relerror(&x1, &x);
2856     if (float_cmp(&x1, &max) > 0)
2857     {
2858       float_copy(&max, &x1, EXACT);
2859       if (float_getexponent(&x1) >= -99)
2860       {
2861         printf("exceeding error for test case %d: ", i);
2862         float_getscientific(buf, 50, &max);
2863         printf("%s\n", buf);
2864         return 0;
2865       }
2866     }
2867   }
2868   float_getscientific(buf, 50, &max);
2869   printf("max error arctannear0: %s\n", buf);
2870   float_free(&tmp);
2871   float_free(&x);
2872   float_free(&x1);
2873   float_free(&max);
2874   return 1;
2875 }
2876 
test_cosminus1near0()2877 static int test_cosminus1near0()
2878 {
2879   floatstruct x, x1, tmp, max;
2880   int i;
2881   char buf[50];
2882 
2883   float_create(&x);
2884   float_create(&x1);
2885   float_create(&tmp);
2886   float_create(&max);
2887   float_setzero(&max);
2888 
2889   printf("%s\n", "testing cosminus1near0");
2890 
2891   printf("verifying special argument x == 0:\n");
2892   float_setzero(&x);
2893   cosminus1near0(&x, 100);
2894   if (!float_iszero(&x))
2895   {
2896     printf("FAILED\n");
2897     return 0;
2898   }
2899 
2900   /* testing the validity of the series evaluation */
2901   printf("verifying result:\n");
2902   float_setasciiz(&x, "0.01");
2903   cosminus1near0(&x, 100);
2904   float_setasciiz(&x1,"-.4999958333472221974206624779332678752941601"
2905                       "972288887772423135353991187035650836487445623"
2906                       "870262734376943805848695816541718420700624513737e-4");
2907   if (!_cmprelerror(&x1, &x, -99))
2908   {
2909     printf("FAILED for x == 0.01\n");
2910     return 0;
2911   }
2912 
2913   printf("testing error limit:\n");
2914   /* overall scan for maximum relative error */
2915   float_setscientific(&tmp, ".0001", NULLTERMINATED);
2916   for (i = -1; ++i <= 100;)
2917   {
2918     float_muli(&x, &tmp, i, EXACT);
2919     _sub_ulp(&x, 101);
2920     float_copy(&x1, &x, EXACT);
2921     cosminus1near0(&x,100);
2922     cosminus1near0(&x1, 110);
2923     _relerror(&x1, &x);
2924     if (float_cmp(&x1, &max) > 0)
2925     {
2926       float_copy(&max, &x1, EXACT);
2927       if (float_getexponent(&x1) >= -99)
2928       {
2929         printf("exceeding error for test case %d: ", i);
2930         float_getscientific(buf, 50, &max);
2931         printf("%s\n", buf);
2932         return 0;
2933       }
2934     }
2935   }
2936   float_getscientific(buf, 50, &max);
2937   printf("max error cosminus1near0: %s\n", buf);
2938   float_free(&tmp);
2939   float_free(&x);
2940   float_free(&x1);
2941   float_free(&max);
2942   return 1;
2943 }
2944 
test_lnxplus1near0()2945 static int test_lnxplus1near0()
2946 {
2947   floatstruct x, x1, tmp, max;
2948   int i;
2949   char buf[50];
2950 
2951   printf("testing _lnxplus1near0\n");
2952 
2953   float_create(&x);
2954   float_create(&x1);
2955   float_create(&tmp);
2956   float_create(&max);
2957 
2958   /* verifying function result */
2959   printf("verifying result:\n");
2960   float_setasciiz(&x, "0.01");
2961   float_setasciiz(&tmp,".009950330853168082848215357544260741688"
2962                        "6796099400587978646095597668666642476389"
2963                        "1103268569656276016116452560517384648478");
2964   _lnxplus1near0(&x, 100);
2965   if (!_cmprelerror(&tmp, &x, -99))
2966   {
2967     printf("FAILED\n");
2968     return 0;
2969   }
2970 
2971   printf("verifying special argument x == 0:\n");
2972   float_setzero(&x);
2973   _lnxplus1near0(&x, 100);
2974   if (!float_iszero(&x))
2975   {
2976     printf("FAILED\n");
2977     return 0;
2978   }
2979 
2980   /* overall scan for maximum relative error */
2981   printf("testing error limit:\n");
2982   float_setzero(&max);
2983   float_setscientific(&tmp, ".0002", NULLTERMINATED);
2984   for (i = -100; ++i <= 100;)
2985   {
2986     float_muli(&x, &tmp, i, EXACT);
2987     _sub_ulp(&x, 101);
2988     float_copy(&x1, &x, EXACT);
2989     _lnxplus1near0(&x,100);
2990     _lnxplus1near0(&x1, 110);
2991     _relerror(&x1, &x);
2992     if (float_cmp(&x1, &max) > 0)
2993     {
2994       float_copy(&max, &x1, EXACT);
2995       if (float_getexponent(&x1) >= -99)
2996       {
2997         printf("exceeding error for test case %d: ", i);
2998         float_getscientific(buf, 50, &max);
2999         printf("%s\n", buf);
3000         return 0;
3001       }
3002     }
3003   }
3004   float_getscientific(buf, 50, &max);
3005   printf("max error _lnxplus1near0: %s\n", buf);
3006   float_free(&tmp);
3007   float_free(&x);
3008   float_free(&x1);
3009   float_free(&max);
3010   return 1;
3011 }
3012 
test_lnreduce()3013 static int test_lnreduce()
3014 {
3015   floatstruct max, x, step, delta, ofs, tmp, lnfactor, cmp;
3016   int i;
3017   char buf[50];
3018 
3019   printf("testing _reduce\n");
3020 
3021   float_create(&x);
3022   float_create(&max);
3023   float_create(&step);
3024   float_create(&delta);
3025   float_create(&ofs);
3026   float_create(&tmp);
3027   float_create(&lnfactor);
3028   float_create(&cmp);
3029   float_setzero(&max);
3030   float_setasciiz(&step, "0.01");
3031   float_setasciiz(&ofs, "0.005");
3032   float_setasciiz(&delta, "0.0049999999");
3033   float_setasciiz(&cmp, "0.01");
3034   printf("testing boundary case -0.4\n");
3035   float_setasciiz(&x, "-.4");
3036   _lnreduce(&x, &lnfactor, 10);
3037   float_abs(&x);
3038   if (float_cmp(&x, &cmp) > 0)
3039   {
3040     float_getscientific(buf, 50, &x);
3041     printf("reduction failed for x=-0.4: %s\n", buf);
3042     return 0;
3043   }
3044   float_abs(&lnfactor);
3045   float_getsignificand(buf, 1, &lnfactor);
3046   if (float_getexponent(&lnfactor) >= 0
3047      || (float_getexponent(&lnfactor) == -1 && buf[0] >= '7'))
3048   {
3049     printf("guess incorrect for x=-0.4\n");
3050     return 1;
3051   }
3052   for (i = -41; ++i < 100;)
3053   {
3054     if (i == -1 || i == 0)
3055       continue;
3056     float_muli(&tmp, &step, i, EXACT);
3057     float_add(&tmp, &tmp, &ofs, EXACT);
3058     float_sub(&x, &tmp, &delta, EXACT);
3059     _lnreduce(&x, &lnfactor, 10);
3060     float_abs(&x);
3061     if(float_cmp(&x, &max) > 0)
3062     {
3063       float_copy(&max, &x, EXACT);
3064       if (float_cmp(&x, &cmp) > 0)
3065       {
3066         float_getscientific(buf, 50, &x);
3067         printf("reduction failed for test case %d: %s\n", i, buf);
3068         return 0;
3069       }
3070     }
3071     float_abs(&lnfactor);
3072     float_getsignificand(buf, 1, &lnfactor);
3073     if (float_getexponent(&lnfactor) >= 0
3074        || (float_getexponent(&lnfactor) == -1 && buf[0] >= '7'))
3075     {
3076       printf("guess incorrect for test case %d\n", i);
3077       return 1;
3078     }
3079     float_add(&x, &tmp, &delta, EXACT);
3080     _lnreduce(&x, &lnfactor, 10);
3081     float_abs(&x);
3082     if(float_cmp(&x, &max) > 0)
3083     {
3084       float_copy(&max, &x, EXACT);
3085       if (float_cmp(&x, &cmp) >0)
3086       {
3087         float_getscientific(buf, 50, &x);
3088         printf("reduction failed for test case %d: %s\n", i, buf);
3089         return 0;
3090       }
3091     }
3092   }
3093   float_getscientific(buf, 50, &max);
3094   printf("max reduced value: %s\n", buf);
3095   float_free(&x);
3096   float_free(&max);
3097   float_free(&step);
3098   float_free(&delta);
3099   float_free(&ofs);
3100   float_free(&tmp);
3101   float_free(&lnfactor);
3102   float_free(&cmp);
3103   return 1;
3104 }
3105 
test_lnxplus1lt1()3106 static int test_lnxplus1lt1()
3107 {
3108   floatstruct x, x1, max, step, ofs, tmp, ref;
3109   int i;
3110   char buf[50];
3111 
3112   printf("testing _lnxplus1lt1\n");
3113 
3114   float_create(&x);
3115   float_create(&x1);
3116   float_create(&max);
3117   float_create(&step);
3118   float_create(&ofs);
3119   float_create(&tmp);
3120   float_create(&ref);
3121 
3122   printf("verifying special argument x == 0:\n");
3123   float_setzero(&x);
3124   _lnxplus1lt1(&x, 100);
3125   if (!float_iszero(&x))
3126   {
3127     printf("FAILED\n");
3128     return 0;
3129   }
3130 
3131   printf("verifying special argument x == -0.4:\n");
3132   float_copy(&x, &cMinus0_4, EXACT);
3133   _lnxplus1lt1(&x, 100);
3134   float_setasciiz(&x1, "-.510825623765990683205514096303661934878110"
3135                        "79644576827017795355783668469448904879775651"
3136                        "81232794475220119962739557576971573560010034");
3137   if (!_cmprelerror(&x1, &x, -99))
3138   {
3139     printf("FAILED\n");
3140     return 0;
3141   }
3142 
3143   printf("verifying function results\n");
3144   float_setasciiz(&step, "0.005");
3145   float_copy(&ref, &step, EXACT);
3146   float_copy(&x, &step, EXACT);
3147   _lnxplus1near0(&ref, 130);
3148   i = 1;
3149   while(float_cmp(&x, &c1) < 0)
3150   {
3151     float_copy(&x1, &x, EXACT);
3152     _lnxplus1lt1(&x, 100);
3153     float_muli(&tmp, &ref, i, 130);
3154     _relerror(&tmp, &x);
3155     if (float_getexponent(&tmp) >= -99)
3156     {
3157       float_getscientific(buf, 50, &tmp);
3158       printf("%s\n", buf);
3159       printf("FAILED for test case %d\n", i);
3160       return 0;
3161     }
3162     float_mul(&tmp, &step, &x1, 130);
3163     float_add(&tmp, &tmp, &step, EXACT);
3164     float_add(&x, &x1, &tmp, 130);
3165     ++i;
3166   }
3167   float_setasciiz(&step, "-0.005");
3168   float_copy(&ref, &step, EXACT);
3169   float_copy(&x, &step, EXACT);
3170   _lnxplus1near0(&ref, 130);
3171   i = 1;
3172   while(float_cmp(&x, &cMinus0_4) >= 0)
3173   {
3174     float_copy(&x1, &x, EXACT);
3175     _lnxplus1lt1(&x, 100);
3176     float_muli(&tmp, &ref, i, 130);
3177     _relerror(&tmp, &x);
3178     if (float_getexponent(&tmp) >= -99)
3179     {
3180       float_getscientific(buf, 50, &tmp);
3181       printf("%s\n", buf);
3182       printf("FAILED for test case %d\n", i);
3183       return 0;
3184     }
3185     float_mul(&tmp, &step, &x1, 130);
3186     float_add(&tmp, &tmp, &step, EXACT);
3187     float_add(&x, &x1, &tmp, 130);
3188     ++i;
3189   }
3190 
3191   printf("testing error limit:\n");
3192   float_setzero(&max);
3193   float_setasciiz(&step, "0.01");
3194   float_setasciiz(&ofs, "0.00117436738983647399324678823992433673"
3195          "24672389823467828246764829833467849839838778485784386584539"
3196          "85343784568643548923998439823432792346");
3197   for(i = -41; ++i < 100;)
3198   {
3199     float_setinteger(&tmp, i);
3200     float_mul(&tmp, &tmp, &step, EXACT);
3201     float_add(&x, &tmp, &ofs, EXACT);
3202     float_copy(&tmp, &x, EXACT);
3203     _lnxplus1lt1(&x, 100);
3204     _lnxplus1lt1(&tmp, 110);
3205     _relerror(&x, &tmp);
3206     if (float_cmp(&x, &max) > 0)
3207     {
3208       float_copy(&max, &x, EXACT);
3209       if (float_getexponent(&x) >= -99)
3210       {
3211         printf("exceeding error in test case %d: ", i);
3212         float_getscientific(buf, 50, &max);
3213         printf("%s\n", buf);
3214         return 0;
3215       }
3216     }
3217   }
3218   float_getscientific(buf, 50, &max);
3219   printf("max error _lnxplus1: %s\n", buf);
3220   float_free(&x);
3221   float_free(&x1);
3222   float_free(&max);
3223   float_free(&step);
3224   float_free(&ofs);
3225   float_free(&tmp);
3226   float_free(&ref);
3227   return 1;
3228 }
3229 
test_ln()3230 static int test_ln()
3231 {
3232   floatstruct x, max, step, ofs, tmp;
3233   int i;
3234   char buf[50];
3235 
3236   printf("testing _ln\n");
3237 
3238   float_create(&x);
3239   float_create(&max);
3240   float_create(&step);
3241   float_create(&ofs);
3242   float_create(&tmp);
3243 
3244   printf("verifying special argument x == 1:\n");
3245   float_copy(&x, &c1, EXACT);
3246   _ln(&x, 100);
3247   if (!float_iszero(&x))
3248   {
3249     printf("FAILED\n");
3250     return 0;
3251   }
3252 
3253   printf("verifying function results:\n");
3254   for (i = 1; ++i < 10;)
3255   {
3256     switch(i)
3257     {
3258     case 2:
3259       float_copy(&tmp, &cLn2, 110);
3260       break;
3261     case 3:
3262       float_copy(&tmp, &cLn3, 110);
3263       break;
3264     case 4:
3265       float_muli(&tmp, &cLn2, 2, 110);
3266       break;
3267     case 5:
3268       float_sub(&tmp, &cLn10, &cLn2, 110);
3269       break;
3270     case 6:
3271       float_add(&tmp, &cLn2, &cLn3, 110);
3272       break;
3273     case 7:
3274       float_copy(&tmp, &cLn7, 110);
3275       break;
3276     case 8:
3277       float_muli(&tmp, &cLn2, 3, 110);
3278       break;
3279     case 9:
3280       float_muli(&tmp, &cLn3, 2, 110);
3281       break;
3282     }
3283     float_setinteger(&x, i);
3284     _ln(&x, 100);
3285     if (!_cmprelerror(&tmp, &x, -99))
3286     {
3287       float_getscientific(buf, 50, &tmp);
3288       printf("FAILED for argument %d: %s\n", i, buf);
3289       return 0;
3290     }
3291   }
3292 
3293   printf("testing exponent handling\n");
3294   float_setinteger(&x, 20);
3295   _ln(&x, 100);
3296   float_add(&tmp, &cLn2, &cLn10, 110);
3297   if (!_cmprelerror(&tmp, &x, -99))
3298   {
3299     printf("FAILED for exponent 1\n");
3300     return 0;
3301   }
3302   float_setasciiz(&x, "0.2");
3303   _ln(&x, 100);
3304   float_sub(&tmp, &cLn2, &cLn10, 110);
3305   if (!_cmprelerror(&tmp, &x, -99))
3306   {
3307     printf("FAILED for exponent -1\n");
3308     return 0;
3309   }
3310 
3311   printf("testing error limit:\n");
3312   float_setzero(&max);
3313   float_setasciiz(&step, "0.05");
3314   float_setasciiz(&ofs, "0.00147436738983647399324678823992433673"
3315          "24672389823467828246764829833467849839838778485784386584539"
3316          "85343784568643548923998439823432792346");
3317   for(i = 19; ++i < 200;)
3318   {
3319     float_muli(&tmp, &step, i, EXACT);
3320     float_add(&x, &tmp, &ofs, EXACT);
3321     if (i > 63)
3322       float_setexponent(&tmp, -1);
3323     float_copy(&tmp, &x, EXACT);
3324     _ln(&x, 100);
3325     _ln(&tmp, 110);
3326     _relerror(&x, &tmp);
3327     if (float_cmp(&x, &max) > 0)
3328     {
3329       float_copy(&max, &x, EXACT);
3330       if (float_getexponent(&x) >= -99)
3331       {
3332         printf("exceeding error in test case %d: ", i);
3333         float_getscientific(buf, 50, &max);
3334         printf("%s\n", buf);
3335         return 0;
3336       }
3337     }
3338   }
3339   float_getscientific(buf, 50, &max);
3340   printf("max error _ln: %s\n", buf);
3341   float_free(&x);
3342   float_free(&max);
3343   float_free(&step);
3344   float_free(&ofs);
3345   float_free(&tmp);
3346   return 1;
3347 }
3348 
test_lnxplus1()3349 static int test_lnxplus1()
3350 {
3351   floatstruct x, x1;
3352 
3353   printf("testing _lnxplus1\n");
3354   float_create(&x);
3355   float_create(&x1);
3356 
3357   printf("verifying function results:\n");
3358 
3359   float_setasciiz(&x, "-.3");
3360   _lnxplus1(&x, 100);
3361   float_copy(&x1, &cLn7, 110);
3362   float_sub(&x1, &x1, &cLn10, 110);
3363   if (!_cmprelerror(&x1, &x, -99))
3364   {
3365     printf("FAILED x == -0.3\n");
3366     return 0;
3367   }
3368 
3369   float_setasciiz(&x, "6");
3370   _lnxplus1(&x, 100);
3371   if (!_cmprelerror(&x, &cLn7, -99))
3372   {
3373     printf("FAILED x == 6\n");
3374     return 0;
3375   }
3376   float_free(&x);
3377   float_free(&x1);
3378   return 1;
3379 }
3380 
test_artanh1minusx()3381 static int test_artanh1minusx()
3382 {
3383   floatstruct x, tmp, max, step, ofs;
3384   int i;
3385   char buf[50];
3386 
3387   printf("testing _artanh1minusx\n");
3388 
3389   float_create(&x);
3390   float_create(&tmp);
3391   float_create(&max);
3392   float_create(&step);
3393   float_create(&ofs);
3394   printf("verifying function results:\n");
3395 
3396   float_copy(&x, &c1Div2, EXACT);
3397   _artanh1minusx(&x, 100);
3398   float_copy(&tmp, &cLn3, 110);
3399   float_mul(&tmp, &tmp, &c1Div2, 110);
3400   if (!_cmprelerror(&tmp, &x, -99))
3401   {
3402     printf("FAILED\n");
3403     return 0;
3404   }
3405 
3406   printf("testing error limit:\n");
3407   float_setzero(&max);
3408   float_setasciiz(&step, "0.01");
3409   float_setasciiz(&ofs, "0.00147436738983647399324678823992433673"
3410          "24672389823467828246764829833467849839838778485784386584539"
3411          "85343784568643548923998439823432792346");
3412   for(i = 0; ++i < 50;)
3413   {
3414     float_muli(&tmp, &step, i, EXACT);
3415     float_add(&x, &tmp, &ofs, EXACT);
3416     float_copy(&tmp, &x, EXACT);
3417     _artanh1minusx(&x, 100);
3418     _artanh1minusx(&tmp, 110);
3419     _relerror(&x, &tmp);
3420     if (float_cmp(&x, &max) > 0)
3421     {
3422       float_copy(&max, &x, EXACT);
3423       if (float_getexponent(&x) >= -99)
3424       {
3425         printf("exceeding error in test case %d: ", i);
3426         float_getscientific(buf, 50, &max);
3427         printf("%s\n", buf);
3428         return 0;
3429       }
3430     }
3431   }
3432   float_getscientific(buf, 50, &max);
3433   printf("max error _artanh1minusx: %s\n", buf);
3434 
3435   float_free(&x);
3436   float_free(&tmp);
3437   float_free(&max);
3438   float_free(&step);
3439   float_free(&ofs);
3440   return 1;
3441 }
3442 
test_artanhlt0_5()3443 static int test_artanhlt0_5()
3444 {
3445   floatstruct x, tmp, max, step, ofs;
3446   int i;
3447   char buf[50];
3448 
3449   printf("testing _artanhlt0_5\n");
3450 
3451   float_create(&x);
3452   float_create(&tmp);
3453   float_create(&max);
3454   float_create(&step);
3455   float_create(&ofs);
3456   printf("verifying function results:\n");
3457 
3458   float_copy(&x, &c1Div2, EXACT);
3459   _artanhlt0_5(&x, 100);
3460   float_copy(&tmp, &cLn3, 110);
3461   float_mul(&tmp, &tmp, &c1Div2, 110);
3462   if (!_cmprelerror(&tmp, &x, -99))
3463   {
3464     printf("FAILED\n");
3465     return 0;
3466   }
3467 
3468   printf("testing error limit:\n");
3469   float_setzero(&max);
3470   float_setasciiz(&step, "0.01");
3471   float_setasciiz(&ofs, "0.00147436738983647399324678823992433673"
3472          "24672389823467828246764829833467849839838778485784386584539"
3473          "85343784568643548923998439823432792346");
3474   for(i = 0; ++i < 50;)
3475   {
3476     float_muli(&tmp, &step, i, EXACT);
3477     float_add(&x, &tmp, &ofs, EXACT);
3478     float_copy(&tmp, &x, EXACT);
3479     _artanhlt0_5(&x, 100);
3480     _artanhlt0_5(&tmp, 110);
3481     _relerror(&x, &tmp);
3482     if (float_cmp(&x, &max) > 0)
3483     {
3484       float_copy(&max, &x, EXACT);
3485       if (float_getexponent(&x) >= -99)
3486       {
3487         printf("exceeding error in test case %d: ", i);
3488         float_getscientific(buf, 50, &max);
3489         printf("%s\n", buf);
3490         return 0;
3491       }
3492     }
3493   }
3494   float_getscientific(buf, 50, &max);
3495   printf("max error _artanh1minusx: %s\n", buf);
3496 
3497   float_free(&x);
3498   float_free(&tmp);
3499   float_free(&max);
3500   float_free(&step);
3501   float_free(&ofs);
3502  return 1;
3503 }
3504 
test_arsinh()3505 static int test_arsinh()
3506 {
3507   floatstruct x, tmp, max, step, ofs;
3508   int i;
3509   char buf[50];
3510 
3511   printf("testing _arsinh\n");
3512 
3513   float_create(&x);
3514   float_create(&tmp);
3515   float_create(&max);
3516   float_create(&step);
3517   float_create(&ofs);
3518 
3519   printf("verifying function results:\n");
3520   float_setzero(&x);
3521   _arsinh(&x, 100);
3522   if(!float_iszero(&x))
3523   {
3524     printf("FAILED for x==0\n");
3525     return 0;
3526   }
3527   float_setasciiz(&x, "1e-1000");
3528   float_copy(&tmp, &x, EXACT);
3529   _arsinh(&x, 100);
3530   if (!_cmprelerror(&tmp, &x, -99))
3531   {
3532     printf("FAILED for x==1e-1000\n");
3533     return 0;
3534   }
3535   float_setasciiz(&x, "0.1");
3536   float_setasciiz(&tmp, ".099834078899207563327303124704769443267712"
3537                         "9117088250107423826956515917683936134651063"
3538                         "484492769032061884984061246778732266658350084462074");
3539   _arsinh(&x, 100);
3540   if (!_cmprelerror(&tmp, &x, -99))
3541   {
3542     printf("FAILED for x==0.1\n");
3543     return 0;
3544   }
3545   float_setasciiz(&x, "4");
3546   float_setasciiz(&tmp, "2.09471254726110129424482284606552865345315"
3547                         "1048198673265886805979926247949695627249150"
3548                         "4293654887408011476586881386829965289261091");
3549   _arsinh(&x, 100);
3550   if (!_cmprelerror(&tmp, &x, -99))
3551   {
3552     printf("FAILED for x==4\n");
3553     return 0;
3554   }
3555   float_setasciiz(&x, "1e100");
3556   float_muli(&tmp, &cLn10, 100, 110);
3557   float_add(&tmp, &tmp, &cLn2, 110);
3558   _arsinh(&x, 100);
3559   if (!_cmprelerror(&tmp, &x, -99))
3560   {
3561     printf("FAILED for x==1e100\n");
3562     return 0;
3563   }
3564 
3565   printf("testing error limit:\n");
3566   float_setzero(&max);
3567   float_setasciiz(&step, "0.05");
3568   float_setasciiz(&ofs, "0.00147436738983647399324678823992433673"
3569          "24672389823467828246764829833467849839838778485784386584539"         "85343784568643548923998439823432792346");
3570   for(i = 0; ++i < 200;)
3571   {
3572     float_muli(&tmp, &step, i, EXACT);
3573     float_add(&x, &tmp, &ofs, EXACT);
3574     float_copy(&tmp, &x, EXACT);
3575     _arsinh(&x, 100);
3576     _arsinh(&tmp, 110);
3577     _relerror(&x, &tmp);
3578     if (float_cmp(&x, &max) > 0)
3579     {
3580       float_copy(&max, &x, EXACT);
3581       if (float_getexponent(&x) >= -99)
3582       {
3583         printf("exceeding error in test case %d: ", i);
3584         float_getscientific(buf, 50, &max);
3585         printf("%s\n", buf);
3586         return 0;
3587       }
3588     }
3589   }
3590   float_getscientific(buf, 50, &max);
3591   printf("max error _arsinh: %s\n", buf);
3592 
3593   float_free(&x);
3594   float_free(&tmp);
3595   float_free(&max);
3596   float_free(&step);
3597   float_free(&ofs);
3598   return 1;
3599 }
3600 
test_arcoshxplus1()3601 static int test_arcoshxplus1()
3602 {
3603   floatstruct x, tmp, max, step, ofs;
3604   int i;
3605   char buf[50];
3606 
3607   printf("testing _arcoshxplus1\n");
3608 
3609   float_create(&x);
3610   float_create(&tmp);
3611   float_create(&max);
3612   float_create(&step);
3613   float_create(&ofs);
3614 
3615   printf("verifying function results:\n");
3616   float_setzero(&x);
3617   _arcoshxplus1(&x, 100);
3618   if(!float_iszero(&x))
3619   {
3620     printf("FAILED for x==0\n");
3621     return 0;
3622   }
3623   float_setinteger(&x, 10);
3624   float_setasciiz(&tmp, "3.08896990484460301791647985373629509453345"
3625                         "4441136435131225532448209215351305027698930"
3626                         "521085626874864770396311532541165684221072841899917");
3627   _arcoshxplus1(&x, 100);
3628   if (!_cmprelerror(&tmp, &x, -99))
3629   {
3630     printf("FAILED for x==10\n");
3631     return 0;
3632   }
3633 
3634   printf("testing error limit:\n");
3635   float_setzero(&max);
3636   float_setasciiz(&step, "0.05");
3637   float_setasciiz(&ofs, "0.00147436738983647399324678823992433673"
3638          "24672389823467828246764829833467849839838778485784386584539"
3639          "85343784568643548923998439823432792346");
3640   for(i = 0; ++i < 200;)
3641   {
3642     float_muli(&tmp, &step, i, EXACT);
3643     float_add(&x, &tmp, &ofs, EXACT);
3644     float_copy(&tmp, &x, EXACT);
3645     _arcoshxplus1(&x, 100);
3646     _arcoshxplus1(&tmp, 110);
3647     _relerror(&x, &tmp);
3648     if (float_cmp(&x, &max) > 0)
3649     {
3650       float_copy(&max, &x, EXACT);
3651       if (float_getexponent(&x) >= -99)
3652       {
3653         printf("exceeding error in test case %d: ", i);
3654         float_getscientific(buf, 50, &max);
3655         printf("%s\n", buf);
3656         return 0;
3657       }
3658     }
3659   }
3660   for(i = 0; ++i < 200;)
3661   {
3662     float_muli(&tmp, &step, i, EXACT);
3663     float_add(&x, &tmp, &ofs, EXACT);
3664     float_copy(&tmp, &x, EXACT);
3665     _arcoshxplus1(&x, 100);
3666     _arcoshxplus1(&tmp, 110);
3667     _relerror(&x, &tmp);
3668     if (float_cmp(&x, &max) > 0)
3669     {
3670       float_copy(&max, &x, EXACT);
3671       if (float_getexponent(&x) >= -99)
3672       {
3673         printf("exceeding error in test case %d: ", i);
3674         float_getscientific(buf, 50, &max);
3675         printf("%s\n", buf);
3676         return 0;
3677       }
3678     }
3679   }
3680   float_getscientific(buf, 50, &max);
3681   printf("max error _arcoshxplus1: %s\n", buf);
3682 
3683   float_free(&tmp);
3684   float_free(&x);
3685   float_free(&max);
3686   float_free(&step);
3687   float_free(&ofs);
3688   return 1;
3689 }
3690 
test_coshminus1lt1()3691 static int test_coshminus1lt1()
3692 {
3693   floatstruct x, x1, tmp, max;
3694   int i;
3695   char buf[50];
3696 
3697   printf("%s\n", "testing _coshminus1lt1");
3698 
3699   float_create(&x);
3700   float_create(&x1);
3701   float_create(&tmp);
3702   float_create(&max);
3703   float_setzero(&max);
3704 
3705   printf("verifying special argument x == 0:\n");
3706   float_setzero(&x);
3707   _coshminus1lt1(&x, 100);
3708   if (!float_iszero(&x))
3709   {
3710     printf("FAILED x== 0\n");
3711     return 0;
3712   }
3713 
3714   /* testing the validity of the reduction */
3715   printf("verifying result:\n");
3716   float_setasciiz(&x, "0.5");
3717   float_copy(&tmp, &x, EXACT);
3718   float_arcoshxplus1(&x, 110);
3719   _coshminus1lt1(&x, 100);
3720   if (!_cmprelerror(&tmp, &x, -99))
3721   {
3722     printf("FAILED for arcosh(1.5)-1\n");
3723     return 0;
3724   }
3725 
3726   printf("testing error limit:\n");
3727   /* overall scan for maximum relative error */
3728   float_setasciiz(&tmp, ".001");
3729   for (i = -1; ++i <= 1000;)
3730   {
3731     float_muli(&x, &tmp, i, EXACT);
3732     _sub_ulp(&x, 101);
3733     float_copy(&x1, &x, EXACT);
3734     _coshminus1lt1(&x,100);
3735     _coshminus1lt1(&x1, 110);
3736     _relerror(&x1, &x);
3737     if (float_cmp(&x1, &max) > 0)
3738     {
3739       float_copy(&max, &x1, EXACT);
3740       if (float_getexponent(&x1) >= -99)
3741       {
3742         printf("exceeding error for test case %d: ", i);
3743         float_getscientific(buf, 50, &max);
3744         printf("%s\n", buf);
3745         return 0;
3746       }
3747     }
3748   }
3749   float_getscientific(buf, 50, &max);
3750   printf("max error _coshminus1lt1: %s\n", buf);
3751 
3752   float_free(&tmp);
3753   float_free(&x);
3754   float_free(&x1);
3755   float_free(&max);
3756   return 1;
3757 }
3758 
test_sinhlt1()3759 static int test_sinhlt1()
3760 {
3761   floatstruct x, x1, tmp, max;
3762   int i;
3763   char buf[50];
3764 
3765   printf("%s\n", "testing _sinhlt1");
3766 
3767   float_create(&x);
3768   float_create(&x1);
3769   float_create(&tmp);
3770   float_create(&max);
3771   float_setzero(&max);
3772 
3773   printf("verifying special argument x == 0:\n");
3774   float_setzero(&x);
3775   _sinhlt1(&x, 100);
3776   if (!float_iszero(&x))
3777   {
3778     printf("FAILED for x== 0\n");
3779     return 0;
3780   }
3781 
3782   printf("verifying positive result:\n");
3783   float_setasciiz(&x, "1");
3784   float_copy(&tmp, &x, EXACT);
3785   float_arsinh(&x, 110);
3786   _sinhlt1(&x, 100);
3787   if (!_cmprelerror(&tmp, &x, -99))
3788   {
3789     printf("FAILED\n");
3790     return 0;
3791   }
3792   printf("verifying negative result:\n");
3793   float_setasciiz(&x, "-1");
3794   float_copy(&tmp, &x, EXACT);
3795   float_arsinh(&x, 110);
3796   _sinhlt1(&x, 100);
3797   if (!_cmprelerror(&tmp, &x, -99))
3798   {
3799     printf("FAILED\n");
3800     return 0;
3801   }
3802 
3803   printf("testing error limit:\n");
3804   /* overall scan for maximum relative error */
3805   float_setasciiz(&tmp, ".001");
3806   for (i = -1; ++i <= 1000;)
3807   {
3808     float_muli(&x, &tmp, i, EXACT);
3809     _sub_ulp(&x, 101);
3810     float_copy(&x1, &x, EXACT);
3811     _sinhlt1(&x,100);
3812     _sinhlt1(&x1, 110);
3813     _relerror(&x1, &x);
3814     if (float_cmp(&x1, &max) > 0)
3815     {
3816       float_copy(&max, &x1, EXACT);
3817       if (float_getexponent(&x1) >= -99)
3818       {
3819         printf("exceeding error for test case %d: ", i);
3820         float_getscientific(buf, 50, &max);
3821         printf("%s\n", buf);
3822         return 0;
3823       }
3824     }
3825   }
3826   float_getscientific(buf, 50, &max);
3827   printf("max error _sinhlt1: %s\n", buf);
3828 
3829   float_free(&tmp);
3830   float_free(&x);
3831   float_free(&x1);
3832   float_free(&max);
3833   return 1;
3834 }
3835 
test_expminus1lt1()3836 static int test_expminus1lt1()
3837 {
3838   floatstruct x, x1, tmp, max;
3839   int i;
3840   char buf[50];
3841 
3842   printf("%s\n", "testing _expminus1lt1");
3843 
3844   float_create(&x);
3845   float_create(&x1);
3846   float_create(&tmp);
3847   float_create(&max);
3848   float_setzero(&max);
3849 
3850   printf("verifying special argument x == 0:\n");
3851   float_setzero(&x);
3852   _expminus1lt1(&x, 100);
3853   if (!float_iszero(&x))
3854   {
3855     printf("FAILED for x== 0\n");
3856     return 0;
3857   }
3858 
3859   printf("verifying positive result:\n");
3860   float_setasciiz(&x, "1");
3861   float_copy(&tmp, &x, EXACT);
3862   float_lnxplus1(&x, 110);
3863   _expminus1lt1(&x, 100);
3864   if (!_cmprelerror(&tmp, &x, -99))
3865   {
3866     printf("FAILED\n");
3867     return 0;
3868   }
3869   printf("verifying negative result:\n");  float_setasciiz(&x, "-.5");
3870   float_copy(&tmp, &x, EXACT);
3871   float_lnxplus1(&x, 110);
3872   _expminus1lt1(&x, 100);
3873   if (!_cmprelerror(&tmp, &x, -99))
3874   {
3875     printf("FAILED\n");
3876     return 0;
3877   }
3878 
3879   printf("testing error limit:\n");
3880   /* overall scan for maximum relative error */
3881   float_setasciiz(&tmp, ".001");
3882   for (i = -1001; ++i <= 1000;)
3883   {
3884     float_muli(&x, &tmp, i, EXACT);
3885     _sub_ulp(&x, 101);
3886     float_copy(&x1, &x, EXACT);
3887     _expminus1lt1(&x,100);
3888     _expminus1lt1(&x1, 110);
3889     _relerror(&x1, &x);
3890     if (float_cmp(&x1, &max) > 0)
3891     {
3892       float_copy(&max, &x1, EXACT);
3893       if (float_getexponent(&x1) >= -99)
3894       {
3895         printf("exceeding error for test case %d: ", i);
3896         float_getscientific(buf, 50, &max);
3897         printf("%s\n", buf);
3898         return 0;
3899       }
3900     }
3901   }
3902   float_getscientific(buf, 50, &max);
3903   printf("max error _expminus1lt1: %s\n", buf);
3904 
3905   float_free(&tmp);
3906   float_free(&x);
3907   float_free(&x1);
3908   float_free(&max);
3909   return 1;
3910 }
3911 
test_expltln10()3912 static int test_expltln10()
3913 {
3914   floatstruct x, x1, tmp, max;
3915   int i;
3916   char buf[50];
3917 
3918   printf("%s\n", "testing _expltln10");
3919 
3920   float_create(&x);
3921   float_create(&x1);
3922   float_create(&tmp);
3923   float_create(&max);
3924   float_setzero(&max);
3925 
3926   printf("verifying special argument x == 0:\n");
3927   float_setzero(&x);
3928   _expltln10(&x, 100);
3929   if (float_cmp(&x, &c1) != 0)
3930   {
3931     printf("FAILED\n");
3932     return 0;
3933   }
3934 
3935   float_setasciiz(&tmp, ".1");
3936   for (i = 0; ++i < 24;)
3937   {
3938     float_muli(&x1, &tmp, i, EXACT);
3939     float_copy(&x, &x1, EXACT);
3940     _expltln10(&x, 100);
3941     float_ln(&x, 110);
3942     if(!_cmprelerror(&x, &x1, -99))
3943     {
3944       float_getscientific(buf, 50, &x1);
3945       printf("FAILED for x == %s\n", buf);
3946       return 0;
3947     }
3948   }
3949 
3950   printf("testing error limit:\n");
3951   /* overall scan for maximum relative error */
3952   float_setasciiz(&tmp, ".005");
3953   for (i = -1; ++i <= 460;)
3954   {
3955     float_muli(&x, &tmp, i, EXACT);
3956     _sub_ulp(&x, 101);
3957     float_copy(&x1, &x, EXACT);
3958     _expltln10(&x,100);
3959     _expltln10(&x1, 110);
3960     _relerror(&x1, &x);
3961     if (float_cmp(&x1, &max) > 0)
3962     {
3963       float_copy(&max, &x1, EXACT);
3964       if (float_getexponent(&x1) >= -99)
3965       {
3966         printf("exceeding error for test case %d: ", i);
3967         float_getscientific(buf, 50, &max);
3968         printf("%s\n", buf);
3969         return 0;
3970       }
3971     }
3972   }
3973   float_getscientific(buf, 50, &max);
3974   printf("max error _expltln10: %s\n", buf);
3975 
3976   float_free(&tmp);
3977   float_free(&x);
3978   float_free(&x1);
3979   float_free(&max);
3980   return 1;
3981 }
3982 
test_exp()3983 static int test_exp()
3984 {
3985   floatstruct x, x1, tmp, max;
3986   int i;
3987   char buf[50];
3988 
3989   printf("%s\n", "testing _exp");
3990 
3991   float_create(&x);
3992   float_create(&x1);
3993   float_create(&tmp);
3994   float_create(&max);
3995   float_setzero(&max);
3996 
3997   printf("verifying special argument x == 0:\n");
3998   float_setzero(&x);
3999   _exp(&x, 100);
4000   if (float_cmp(&x, &c1) != 0)
4001   {
4002     printf("FAILED\n");
4003     return 0;
4004   }
4005 
4006   printf("verifying results:\n");
4007   float_setasciiz(&tmp, "1");
4008   for (i = -2; ++i < 9;)
4009   {
4010     float_setexponent(&tmp, i);
4011     float_copy(&x, &tmp, EXACT);
4012     _exp(&x, 100);
4013     float_ln(&x, 110);
4014     if(!_cmprelerror(&x, &tmp, -99))
4015     {
4016       float_getscientific(buf, 50, &tmp);
4017       printf("FAILED for x == %s\n", buf);
4018       return 0;
4019     }
4020   }
4021 
4022   float_setasciiz(&tmp, "-1");
4023   for (i = -2; ++i < 9;)
4024   {
4025     float_setexponent(&tmp, i);
4026     float_copy(&x, &tmp, EXACT);
4027     _exp(&x, 100);
4028     float_ln(&x, 110);
4029     if(!_cmprelerror(&x, &tmp, -99))
4030     {
4031       float_getscientific(buf, 50, &tmp);
4032       printf("FAILED for x == %s\n", buf);
4033       return 0;
4034     }
4035   }
4036 
4037   printf("testing error limit:\n");
4038   /* overall scan for maximum relative error */
4039   float_setasciiz(&tmp, ".005");
4040   for (i = -461; ++i <= 0;)
4041   {
4042     float_muli(&x, &tmp, i, EXACT);
4043     _sub_ulp(&x, 101);
4044     float_copy(&x1, &x, EXACT);
4045     _exp(&x,100);
4046     _exp(&x1, 110);
4047     _relerror(&x1, &x);
4048     if (float_cmp(&x1, &max) > 0)
4049     {
4050       float_copy(&max, &x1, EXACT);
4051       if (float_getexponent(&x1) >= -99)
4052       {
4053         printf("exceeding error for test case %d: ", i);
4054         float_getscientific(buf, 50, &max);
4055         printf("%s\n", buf);
4056         return 0;
4057       }
4058     }
4059   }
4060   float_muli(&x, &cLn10, EXPMAX, 110);
4061   float_copy(&x1, &x, EXACT);
4062   _exp(&x,100);
4063   _exp(&x1, 110);
4064   _relerror(&x1, &x);
4065   if (float_cmp(&x1, &max) > 0)
4066   {
4067     float_copy(&max, &x1, EXACT);
4068     if (float_getexponent(&x1) >= -99)
4069     {
4070       printf("exceeding error for near overflow case: ");
4071       float_getscientific(buf, 50, &max);
4072       printf("%s\n", buf);
4073       return 0;
4074     }
4075   }
4076   float_getscientific(buf, 50, &max);
4077   printf("max error _exp: %s\n", buf);
4078 
4079   float_free(&tmp);
4080   float_free(&x);
4081   float_free(&x1);
4082   float_free(&max);
4083   return 1;
4084 }
4085 
test_expminus1()4086 static int test_expminus1()
4087 {
4088   floatstruct x, tmp;
4089 
4090   printf("%s\n", "testing _expminus1");
4091 
4092   float_create(&x);
4093   float_create(&tmp);
4094 
4095   printf("verifying special argument x == 0:\n");
4096   float_setzero(&x);
4097   _expminus1(&x, 100);
4098   if (!float_iszero(&x))
4099   {
4100     printf("FAILED\n");
4101     return 0;
4102   }
4103 
4104   printf("verifying results:\n");
4105   float_setasciiz(&x, "-1e100000");
4106   float_setinteger(&tmp, -1);
4107   _expminus1(&x, 100);
4108   if(!_cmprelerror(&x, &tmp, -99))
4109   {
4110     printf("FAILED for x == -1e100000\n");
4111     return 0;
4112   }
4113   float_setasciiz(&x, "-1");
4114   float_setinteger(&tmp, -1);
4115   _expminus1(&x, 100);
4116   float_lnxplus1(&x, 110);
4117   if(!_cmprelerror(&x, &tmp, -99))
4118   {
4119     printf("FAILED for x == -1\n");
4120     return 0;
4121   }
4122   float_setasciiz(&x, "-1e-10");
4123   float_copy(&tmp, &x, EXACT);
4124   _expminus1(&x, 100);
4125   float_lnxplus1(&x, 110);
4126   if(!_cmprelerror(&x, &tmp, -99))
4127   {
4128     printf("FAILED for x == -1e-10\n");
4129     return 0;
4130   }
4131   float_setasciiz(&x, "1e-10");
4132   float_copy(&tmp, &x, EXACT);
4133   _expminus1(&x, 100);
4134   float_lnxplus1(&x, 110);
4135   if(!_cmprelerror(&x, &tmp, -99))
4136   {
4137     printf("FAILED for x == 1e-10\n");
4138     return 0;
4139   }
4140 
4141   float_setasciiz(&x, "1");
4142   float_copy(&tmp, &x, EXACT);
4143   _expminus1(&x, 100);
4144   float_lnxplus1(&x, 110);
4145   if(!_cmprelerror(&x, &tmp, -99))
4146   {
4147     printf("FAILED for x == 1\n");
4148     return 0;
4149   }
4150   float_setasciiz(&x, "100000");
4151   float_copy(&tmp, &x, EXACT);
4152   _expminus1(&x, 100);
4153   float_lnxplus1(&x, 110);
4154   if(!_cmprelerror(&x, &tmp, -99))
4155   {
4156     printf("FAILED for x == 100000\n");
4157     return 0;
4158   }
4159   float_free(&tmp);
4160   float_free(&x);
4161   return 1;
4162 }
4163 
test_coshminus1()4164 static int test_coshminus1()
4165 {
4166   floatstruct x, x1, tmp, max;
4167   int i;
4168   char buf[50];
4169 
4170   printf("%s\n", "testing _coshminus1");
4171 
4172   float_create(&x);
4173   float_create(&tmp);
4174   float_create(&x1);
4175   float_create(&max);
4176   float_setzero(&max);
4177 
4178   printf("verifying function results:\n");
4179   float_setzero(&x);
4180   _coshminus1(&x, 100);
4181   if (!float_iszero(&x))
4182   {
4183     printf("FAILED for x == 0\n");
4184     return 0;
4185   }
4186 
4187   float_setasciiz(&x, ".1");
4188   float_copy(&tmp, &x, EXACT);
4189   _coshminus1(&x, 100);
4190   float_arcoshxplus1(&x, 110);
4191   if(!_cmprelerror(&x, &tmp, -99))
4192   {
4193     printf("FAILED for x == 0.1\n");
4194     return 0;
4195   }
4196 
4197   float_setasciiz(&x, "2");
4198   float_copy(&tmp, &x, EXACT);
4199   _coshminus1(&x, 100);
4200   float_arcoshxplus1(&x, 110);
4201   if(!_cmprelerror(&x, &tmp, -99))
4202   {
4203     printf("FAILED for x == 2\n");
4204     return 0;
4205   }
4206 
4207   float_setasciiz(&x, "10000");
4208   float_copy(&tmp, &x, EXACT);
4209   _coshminus1(&x, 100);
4210   float_arcoshxplus1(&x, 110);
4211   if(!_cmprelerror(&x, &tmp, -99))
4212   {
4213     printf("FAILED for x == 10000\n");
4214     return 0;
4215   }
4216 
4217   printf("testing error limit:\n");
4218   /* overall scan for maximum relative error */
4219   float_setasciiz(&tmp, ".005");
4220   for (i = 200; ++i <= 500;)
4221   {
4222     float_muli(&x, &tmp, i, EXACT);
4223     _sub_ulp(&x, 101);
4224     float_copy(&x1, &x, EXACT);
4225     _coshminus1(&x,100);
4226     _coshminus1(&x1, 110);
4227     _relerror(&x1, &x);
4228     if (float_cmp(&x1, &max) > 0)
4229     {
4230       float_copy(&max, &x1, EXACT);
4231       if (float_getexponent(&x1) >= -99)
4232       {
4233         printf("exceeding error for test case %d: ", i);
4234         float_getscientific(buf, 50, &max);
4235         printf("%s\n", buf);
4236         return 0;
4237       }
4238     }
4239   }
4240   float_getscientific(buf, 50, &max);
4241   printf("max error _coshminus1: %s\n", buf);
4242 
4243   float_free(&tmp);
4244   float_free(&x);
4245   float_free(&x1);
4246   float_free(&max);
4247   return 1;
4248 }
4249 
test_tanhlt0_5()4250 static int test_tanhlt0_5()
4251 {
4252   floatstruct x, x1, tmp, max;
4253   int i;
4254   char buf[50];
4255 
4256   printf("%s\n", "testing _tanhlt0_5");
4257 
4258   float_create(&x);
4259   float_create(&tmp);
4260   float_create(&x1);
4261   float_create(&max);
4262   float_setzero(&max);
4263 
4264   printf("verifying function results:\n");
4265   float_setzero(&x);
4266   _tanhlt0_5(&x, 100);
4267   if (!float_iszero(&x))
4268   {
4269     printf("FAILED for x == 0\n");
4270     return 0;
4271   }
4272 
4273   float_setasciiz(&x, ".1");
4274   float_copy(&tmp, &x, EXACT);
4275   _tanhlt0_5(&x, 100);
4276   float_artanh(&x, 110);
4277   if(!_cmprelerror(&x, &tmp, -99))
4278   {
4279     printf("FAILED for x == 0.1\n");
4280     return 0;
4281   }
4282 
4283   printf("testing error limit:\n");
4284   /* overall scan for maximum relative error */
4285   float_setasciiz(&tmp, ".005");
4286   for (i = 0; ++i <= 100;)
4287   {
4288     float_muli(&x, &tmp, i, EXACT);
4289     _sub_ulp(&x, 101);
4290     float_copy(&x1, &x, EXACT);
4291     _tanhlt0_5(&x,100);
4292     _tanhlt0_5(&x1, 110);
4293     _relerror(&x1, &x);
4294     if (float_cmp(&x1, &max) > 0)
4295     {
4296       float_copy(&max, &x1, EXACT);
4297       if (float_getexponent(&x1) >= -99)
4298       {
4299         printf("exceeding error for test case %d: ", i);
4300         float_getscientific(buf, 50, &max);
4301         printf("%s\n", buf);
4302         return 0;
4303       }
4304     }
4305   }
4306   float_getscientific(buf, 50, &max);
4307   printf("max error _tanhlt0_5: %s\n", buf);
4308 
4309   float_free(&tmp);
4310   float_free(&x);
4311   float_free(&x1);
4312   float_free(&max);
4313   return 1;
4314 }
4315 
test_tanhminus1gt0()4316 static int test_tanhminus1gt0()
4317 {
4318   floatstruct x, x1, tmp, max;
4319   int i;
4320   char buf[50];
4321 
4322   printf("%s\n", "testing _tanhminus1gt0");
4323 
4324   float_create(&x);
4325   float_create(&tmp);
4326   float_create(&x1);
4327   float_create(&max);
4328   float_setzero(&max);
4329 
4330   float_setasciiz(&x, "1");
4331   float_copy(&tmp, &x, EXACT);
4332   _tanhminus1gt0(&x, 100);
4333   float_artanhxplus1(&x, 110);
4334   if(!_cmprelerror(&x, &tmp, -99))
4335   {
4336     printf("FAILED for x == 1\n");
4337     return 0;
4338   }
4339 
4340   printf("testing error limit:\n");
4341   /* overall scan for maximum relative error */
4342   float_setasciiz(&tmp, ".005");
4343   for (i = 0; ++i <= 300;)
4344   {
4345     float_muli(&x, &tmp, i, EXACT);
4346     _sub_ulp(&x, 101);
4347     float_copy(&x1, &x, EXACT);
4348     _tanhminus1gt0(&x,100);
4349     _tanhminus1gt0(&x1, 110);
4350     _relerror(&x1, &x);
4351     if (float_cmp(&x1, &max) > 0)
4352     {
4353       float_copy(&max, &x1, EXACT);
4354       if (float_getexponent(&x1) >= -99)
4355       {
4356         printf("exceeding error for test case %d: ", i);
4357         float_getscientific(buf, 50, &max);
4358         printf("%s\n", buf);
4359         return 0;
4360       }
4361     }
4362   }
4363   for (i = 1; i <= EXPMAX;)
4364   {
4365     float_setinteger(&x, 1);
4366     _sub_ulp(&x, 101);
4367     float_setexponent(&x, i);
4368     i*=10;
4369     float_copy(&x1, &x, EXACT);
4370     _tanhminus1gt0(&x,100);
4371     _tanhminus1gt0(&x1, 110);
4372     _relerror(&x1, &x);
4373     if (float_cmp(&x1, &max) > 0)
4374     {
4375       float_copy(&max, &x1, EXACT);
4376       if (float_getexponent(&x1) >= -99)
4377       {
4378         printf("exceeding error for test case %d: ", i);
4379         float_getscientific(buf, 50, &max);
4380         printf("%s\n", buf);
4381         return 0;
4382       }
4383     }
4384   }
4385   float_getscientific(buf, 50, &max);
4386   printf("max error _tanhminus1gt0: %s\n", buf);
4387 
4388   float_free(&tmp);
4389   float_free(&x);
4390   float_free(&x1);
4391   float_free(&max);
4392   return 1;
4393 }
4394 
test_arctanlt1()4395 static int test_arctanlt1()
4396 {
4397   floatstruct x, tmp, max, step, ofs;
4398   int i;
4399   char buf[50];
4400 
4401   printf("testing _arctanlt1\n");
4402 
4403   float_create(&x);
4404   float_create(&tmp);
4405   float_create(&max);
4406   float_create(&step);
4407   float_create(&ofs);
4408 
4409   printf("verifying function results:\n");
4410   float_setzero(&x);
4411   _arctanlt1(&x, 100);
4412   if(!float_iszero(&x))
4413   {
4414     printf("FAILED for x==0\n");
4415     return 0;
4416   }
4417   float_setasciiz(&x, "-0.5");
4418   float_setasciiz(&tmp, "-.46364760900080611621425623146121440202853"
4419                         "7054286120263810933088720197864165741705300"
4420                         "60028398488789255652985225119083751350581818162501");
4421   _arctanlt1(&x, 100);
4422   if (!_cmprelerror(&tmp, &x, -99))
4423   {
4424     printf("FAILED for x==-0.5\n");
4425     return 0;
4426   }
4427 
4428   printf("testing error limit:\n");
4429   float_setzero(&max);
4430   float_setasciiz(&step, "0.005");
4431   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
4432          "24672389823467828246764829833467849839838778485784386584539"
4433          "85343784568643548923998439823432792346");
4434   for(i = 0; ++i < 200;)
4435   {
4436     float_muli(&tmp, &step, i, EXACT);
4437     float_add(&x, &tmp, &ofs, EXACT);
4438     float_copy(&tmp, &x, EXACT);
4439     _arctanlt1(&x, 100);
4440     _arctanlt1(&tmp, 110);
4441     _relerror(&x, &tmp);
4442     if (float_cmp(&x, &max) > 0)
4443     {
4444       float_copy(&max, &x, EXACT);
4445       if (float_getexponent(&x) >= -99)
4446       {
4447         printf("exceeding error in test case %d: ", i);
4448         float_getscientific(buf, 50, &max);
4449         printf("%s\n", buf);
4450         return 0;
4451       }
4452     }
4453   }
4454   float_getscientific(buf, 50, &max);
4455   printf("max error _arctanlt1: %s\n", buf);
4456 
4457   float_free(&tmp);
4458   float_free(&x);
4459   float_free(&max);
4460   float_free(&step);
4461   float_free(&ofs);
4462   return 1;
4463 }
4464 
test_arctan()4465 static int test_arctan()
4466 {
4467   floatstruct x, tmp, max, step, ofs;
4468   int i;
4469   char buf[50];
4470 
4471   printf("testing _arctan\n");
4472 
4473   float_create(&x);
4474   float_create(&tmp);
4475   float_create(&max);
4476   float_create(&step);
4477   float_create(&ofs);
4478 
4479   float_setasciiz(&x, "-1.5");
4480   float_setasciiz(&tmp, "-.98279372324732906798571061101466601449687"
4481                         "7453631628556761425088317988071549796035389"
4482                         "70653437281731110816513970201193676622994103918188");
4483   _arctan(&x, 100);
4484   if (!_cmprelerror(&tmp, &x, -99))
4485   {
4486     printf("FAILED for x==-1.5\n");
4487     return 0;
4488   }
4489 
4490   printf("testing error limit:\n");
4491   float_setzero(&max);
4492   float_setasciiz(&step, "0.005");
4493   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
4494          "24672389823467828246764829833467849839838778485784386584539"
4495          "85343784568643548923998439823432792346");
4496   for(i = 200; ++i < 400;)
4497   {
4498     float_muli(&tmp, &step, i, EXACT);
4499     float_add(&x, &tmp, &ofs, EXACT);
4500     float_copy(&tmp, &x, EXACT);
4501     _arctan(&x, 100);
4502     _arctan(&tmp, 110);
4503     _relerror(&x, &tmp);
4504     if (float_cmp(&x, &max) > 0)
4505     {
4506       float_copy(&max, &x, EXACT);
4507       if (float_getexponent(&x) >= -99)
4508       {
4509         printf("exceeding error in test case %d: ", i);
4510         float_getscientific(buf, 50, &max);
4511         printf("%s\n", buf);
4512         return 0;
4513       }
4514     }
4515   }
4516   float_getscientific(buf, 50, &max);
4517   printf("max error _arctan: %s\n", buf);
4518 
4519   float_free(&tmp);
4520   float_free(&x);
4521   float_free(&max);
4522   float_free(&step);
4523   float_free(&ofs);
4524   return 1;
4525 }
4526 
test_arccosxplus1lt0_5()4527 static int test_arccosxplus1lt0_5()
4528 {
4529   floatstruct x, tmp, max, step, ofs;
4530   int i;
4531   char buf[50];
4532 
4533   printf("testing _arccosxplus1lt0_5\n");
4534 
4535   float_create(&x);
4536   float_create(&tmp);
4537   float_create(&max);
4538   float_create(&step);
4539   float_create(&ofs);
4540 
4541   printf("verifying function results:\n");
4542   float_setzero(&x);
4543   _arccosxplus1lt0_5(&x, 100);
4544   if(!float_iszero(&x))
4545   {
4546     printf("FAILED for x==0\n");
4547     return 0;
4548   }
4549   float_setasciiz(&x, "-0.5");
4550   float_setasciiz(&tmp, "1.04719755119659774615421446109316762806572"
4551                         "3133125035273658314864102605468762069666209"
4552                         "34494178070568932738269550442743554903128153651686");
4553   _arccosxplus1lt0_5(&x, 100);
4554   if (!_cmprelerror(&tmp, &x, -99))
4555   {
4556     printf("FAILED for x==-0.5\n");
4557     return 0;
4558   }
4559 
4560   printf("testing error limit:\n");
4561   float_setzero(&max);
4562   float_setasciiz(&step, "0.005");
4563   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
4564          "24672389823467828246764829833467849839838778485784386584539"
4565          "85343784568643548923998439823432792346");
4566   for(i = 0; ++i < 100;)
4567   {
4568     float_muli(&tmp, &step, i, EXACT);
4569     float_add(&x, &tmp, &ofs, EXACT);
4570     float_copy(&tmp, &x, EXACT);
4571     _arccosxplus1lt0_5(&x, 100);
4572     _arccosxplus1lt0_5(&tmp, 110);
4573     _relerror(&x, &tmp);
4574     if (float_cmp(&x, &max) > 0)
4575     {
4576       float_copy(&max, &x, EXACT);
4577       if (float_getexponent(&x) >= -99)
4578       {
4579         printf("exceeding error in test case %d: ", i);
4580         float_getscientific(buf, 50, &max);
4581         printf("%s\n", buf);
4582         return 0;
4583       }
4584     }
4585   }
4586   float_getscientific(buf, 50, &max);
4587   printf("max error _arccosxplus1lt0_5: %s\n", buf);
4588 
4589   float_free(&tmp);
4590   float_free(&x);
4591   float_free(&max);
4592   float_free(&step);
4593   float_free(&ofs);
4594   return 1;
4595 }
4596 
test_arcsinlt0_5()4597 static int test_arcsinlt0_5()
4598 {
4599   floatstruct x, tmp, max, step, ofs;
4600   int i;
4601   char buf[50];
4602 
4603   printf("testing _arcsinlt0_5\n");
4604 
4605   float_create(&x);
4606   float_create(&tmp);
4607   float_create(&max);
4608   float_create(&step);
4609   float_create(&ofs);
4610 
4611   printf("verifying function results:\n");
4612   float_setzero(&x);
4613   _arccosxplus1lt0_5(&x, 100);
4614   if(!float_iszero(&x))
4615   {
4616     printf("FAILED for x==0\n");
4617     return 0;
4618   }
4619   float_setasciiz(&x, "-0.5");
4620   float_setasciiz(&tmp, "-.52359877559829887307710723054658381403286"
4621                         "1566562517636829157432051302734381034833104"
4622                         "67247089035284466369134775221371777451564076825843");
4623   _arcsinlt0_5(&x, 100);
4624   if (!_cmprelerror(&tmp, &x, -99))
4625   {
4626     printf("FAILED for x==-0.5\n");
4627     return 0;
4628   }
4629 
4630   printf("testing error limit:\n");
4631   float_setzero(&max);
4632   float_setasciiz(&step, "0.005");
4633   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
4634          "24672389823467828246764829833467849839838778485784386584539"
4635          "85343784568643548923998439823432792346");
4636   for(i = 0; ++i < 100;)
4637   {
4638     float_muli(&tmp, &step, i, EXACT);
4639     float_add(&x, &tmp, &ofs, EXACT);
4640     float_copy(&tmp, &x, EXACT);
4641     _arcsinlt0_5(&x, 100);
4642     _arcsinlt0_5(&tmp, 110);
4643     _relerror(&x, &tmp);
4644     if (float_cmp(&x, &max) > 0)
4645     {
4646       float_copy(&max, &x, EXACT);
4647       if (float_getexponent(&x) >= -99)
4648       {
4649         printf("exceeding error in test case %d: ", i);
4650         float_getscientific(buf, 50, &max);
4651         printf("%s\n", buf);
4652         return 0;
4653       }
4654     }
4655   }
4656   float_getscientific(buf, 50, &max);
4657   printf("max error _arcsinlt0_5: %s\n", buf);
4658 
4659   float_free(&tmp);
4660   float_free(&x);
4661   float_free(&max);
4662   float_free(&step);
4663   float_free(&ofs);
4664   return 1;
4665 }
4666 
test_arccos()4667 static int test_arccos()
4668 {
4669   floatstruct x, tmp, max, step, ofs;
4670   int i;
4671   char buf[50];
4672 
4673   printf("testing _arccos\n");
4674 
4675   float_create(&x);
4676   float_create(&tmp);
4677   float_create(&max);
4678   float_create(&step);
4679   float_create(&ofs);
4680 
4681   printf("verifying function results:\n");
4682   float_setinteger(&x, 1);
4683   _arccos(&x, 100);
4684   if(!float_iszero(&x))
4685   {
4686     printf("FAILED for x==1\n");
4687     return 0;
4688   }
4689   float_setasciiz(&x, "0.5");
4690   float_setasciiz(&tmp, "1.04719755119659774615421446109316762806572"
4691                         "3133125035273658314864102605468762069666209"
4692                         "34494178070568932738269550442743554903128153651686");
4693   _arccos(&x, 100);
4694   if (!_cmprelerror(&tmp, &x, -99))
4695   {
4696     printf("FAILED for x==0.5\n");
4697     return 0;
4698   }
4699   float_setzero(&x);
4700   _arccos(&x, 100);
4701   if (!_cmprelerror(&x, &cPiDiv2, -99))
4702   {
4703     printf("FAILED for x==0\n");
4704     return 0;
4705   }
4706   float_setinteger(&x, -1);
4707   _arccos(&x, 100);
4708   if (!_cmprelerror(&x, &cPi, -99))
4709   {
4710     printf("FAILED for x==-1\n");
4711     return 0;
4712   }
4713 
4714   printf("testing error limit:\n");
4715   float_setzero(&max);
4716   float_setasciiz(&step, "0.01");
4717   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
4718          "24672389823467828246764829833467849839838778485784386584539"
4719          "85343784568643548923998439823432792346");
4720   for(i = -100; ++i < 100;)
4721   {
4722     float_muli(&tmp, &step, i, EXACT);
4723     float_add(&x, &tmp, &ofs, EXACT);
4724     float_copy(&tmp, &x, EXACT);
4725     _arccos(&x, 100);
4726     _arccos(&tmp, 110);
4727     _relerror(&x, &tmp);
4728     if (float_cmp(&x, &max) > 0)
4729     {
4730       float_copy(&max, &x, EXACT);
4731       if (float_getexponent(&x) >= -99)
4732       {
4733         printf("exceeding error in test case %d: ", i);
4734         float_getscientific(buf, 50, &max);
4735         printf("%s\n", buf);
4736         return 0;
4737       }
4738     }
4739   }
4740   float_getscientific(buf, 50, &max);
4741   printf("max error _arccos: %s\n", buf);
4742 
4743   float_free(&tmp);
4744   float_free(&x);
4745   float_free(&max);
4746   float_free(&step);
4747   float_free(&ofs);
4748   return 1;
4749 }
4750 
test_arcsin()4751 static int test_arcsin()
4752 {
4753   floatstruct x, tmp, max, step, ofs;
4754   int i;
4755   char buf[50];
4756 
4757   printf("testing _arcsin\n");
4758 
4759   float_create(&x);
4760   float_create(&tmp);
4761   float_create(&max);
4762   float_create(&step);
4763   float_create(&ofs);
4764 
4765   printf("verifying function results:\n");
4766   float_setzero(&x);
4767   _arcsin(&x, 100);
4768   if(!float_iszero(&x))
4769   {
4770     printf("FAILED for x==0\n");
4771     return 0;
4772   }
4773   float_setasciiz(&x, "-0.5");
4774   float_setasciiz(&tmp, "-.52359877559829887307710723054658381403286"
4775                         "1566562517636829157432051302734381034833104"
4776                         "67247089035284466369134775221371777451564076825843");
4777   _arcsin(&x, 100);
4778   if (!_cmprelerror(&tmp, &x, -99))
4779   {
4780     printf("FAILED for x==-0.5\n");
4781     return 0;
4782   }
4783   float_setinteger(&x, 1);
4784   _arcsin(&x, 100);
4785   if (!_cmprelerror(&x, &cPiDiv2, -99))
4786   {
4787     printf("FAILED for x==1\n");
4788     return 0;
4789   }
4790   float_setinteger(&x, -1);
4791   _arcsin(&x, 100);
4792   float_neg(&x);
4793   if (!_cmprelerror(&x, &cPiDiv2, -99))
4794   {
4795     printf("FAILED for x==-1\n");
4796     return 0;
4797   }
4798 
4799   printf("testing error limit:\n");
4800   float_setzero(&max);
4801   float_setasciiz(&step, "0.005");
4802   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
4803          "24672389823467828246764829833467849839838778485784386584539"
4804          "85343784568643548923998439823432792346");
4805   for(i = 0; ++i < 200;)
4806   {
4807     float_muli(&tmp, &step, i, EXACT);
4808     float_add(&x, &tmp, &ofs, EXACT);
4809     float_copy(&tmp, &x, EXACT);
4810     _arcsin(&x, 100);
4811     _arcsin(&tmp, 110);
4812     _relerror(&x, &tmp);
4813     if (float_cmp(&x, &max) > 0)
4814     {
4815       float_copy(&max, &x, EXACT);
4816       if (float_getexponent(&x) >= -99)
4817       {
4818         printf("exceeding error in test case %d: ", i);
4819         float_getscientific(buf, 50, &max);
4820         printf("%s\n", buf);
4821         return 0;
4822       }
4823     }
4824   }
4825   float_getscientific(buf, 50, &max);
4826   printf("max error _arcsin: %s\n", buf);
4827 
4828   float_free(&tmp);
4829   float_free(&x);
4830   float_free(&max);
4831   float_free(&step);
4832   float_free(&ofs);
4833   return 1;
4834 }
4835 
test_cosminus1ltPiDiv4()4836 static int test_cosminus1ltPiDiv4()
4837 {
4838   floatstruct x, tmp, max, step, ofs;
4839   int i;
4840   char buf[50];
4841 
4842   printf("testing _cosminus1ltPiDiv4\n");
4843 
4844   float_create(&x);
4845   float_create(&tmp);
4846   float_create(&max);
4847   float_create(&step);
4848   float_create(&ofs);
4849 
4850   printf("verifying function results:\n");
4851   float_setzero(&x);
4852   _cosminus1ltPiDiv4(&x, 100);
4853   if(!float_iszero(&x))
4854   {
4855     printf("FAILED for x==0\n");
4856     return 0;
4857   }
4858   float_setasciiz(&x, "-0.5");
4859   float_setasciiz(&tmp, "-.12241743810962728388371841739617034800835"
4860                         "4802890255947002389131684049236725786052594"
4861                         "205815915317741644521599406890946006586172");
4862   _cosminus1ltPiDiv4(&x, 100);
4863   if (!_cmprelerror(&tmp, &x, -99))
4864   {
4865     printf("FAILED for x==-0.5\n");
4866     return 0;
4867   }
4868 
4869   printf("testing error limit:\n");
4870   float_setzero(&max);
4871   float_setasciiz(&step, "0.005");
4872   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
4873          "24672389823467828246764829833467849839838778485784386584539"
4874          "85343784568643548923998439823432792346");
4875   for(i = 0; ++i < 158;)
4876   {
4877     float_muli(&tmp, &step, i, EXACT);
4878     float_add(&x, &tmp, &ofs, EXACT);
4879     float_copy(&tmp, &x, EXACT);
4880     _cosminus1ltPiDiv4(&x, 100);
4881     _cosminus1ltPiDiv4(&tmp, 110);
4882     _relerror(&x, &tmp);
4883     if (float_cmp(&x, &max) > 0)
4884     {
4885       float_copy(&max, &x, EXACT);
4886       if (float_getexponent(&x) >= -99)
4887       {
4888         printf("exceeding error in test case %d: ", i);
4889         float_getscientific(buf, 50, &max);
4890         printf("%s\n", buf);
4891         return 0;
4892       }
4893     }
4894   }
4895   float_getscientific(buf, 50, &max);
4896   printf("max error _cosminus1ltPiDiv4: %s\n", buf);
4897 
4898   float_free(&tmp);
4899   float_free(&x);
4900   float_free(&max);
4901   float_free(&step);
4902   float_free(&ofs);
4903   return 1;
4904 }
4905 
test_sinltPiDiv4()4906 static int test_sinltPiDiv4()
4907 {
4908   floatstruct x, tmp, max, step, ofs;
4909   int i;
4910   char buf[50];
4911 
4912   printf("testing _sinltPiDiv4\n");
4913 
4914   float_create(&x);
4915   float_create(&tmp);
4916   float_create(&max);
4917   float_create(&step);
4918   float_create(&ofs);
4919 
4920   printf("verifying function results:\n");
4921   float_setzero(&x);
4922   _sinltPiDiv4(&x, 100);
4923   if(!float_iszero(&x))
4924   {
4925     printf("FAILED for x==0\n");
4926     return 0;
4927   }
4928   float_setasciiz(&x, "-0.5");
4929   float_setasciiz(&tmp, "-.47942553860420300027328793521557138808180"
4930                         "3367940600675188616613125535000287814832209"
4931                         "63127468434826908613209108450571741781109374860994");
4932   _sinltPiDiv4(&x, 100);
4933   if (!_cmprelerror(&tmp, &x, -99))
4934   {
4935     printf("FAILED for x==-0.5\n");
4936     return 0;
4937   }
4938 
4939   printf("testing error limit:\n");
4940   float_setzero(&max);
4941   float_setasciiz(&step, "0.005");
4942   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
4943          "24672389823467828246764829833467849839838778485784386584539"
4944          "85343784568643548923998439823432792346");
4945   for(i = 0; ++i < 158;)
4946   {
4947     float_muli(&tmp, &step, i, EXACT);
4948     float_add(&x, &tmp, &ofs, EXACT);
4949     float_copy(&tmp, &x, EXACT);
4950     _sinltPiDiv4(&x, 100);
4951     _sinltPiDiv4(&tmp, 110);
4952     _relerror(&x, &tmp);
4953     if (float_cmp(&x, &max) > 0)
4954     {
4955       float_copy(&max, &x, EXACT);
4956       if (float_getexponent(&x) >= -99)
4957       {
4958         printf("exceeding error in test case %d: ", i);
4959         float_getscientific(buf, 50, &max);
4960         printf("%s\n", buf);
4961         return 0;
4962       }
4963     }
4964   }
4965   float_getscientific(buf, 50, &max);
4966   printf("max error _sinltPiDiv4: %s\n", buf);
4967 
4968   float_free(&tmp);
4969   float_free(&x);
4970   float_free(&max);
4971   float_free(&step);
4972   float_free(&ofs);
4973   return 1;
4974 }
4975 
test_tanltPiDiv4()4976 static int test_tanltPiDiv4()
4977 {
4978   floatstruct x, tmp, max, step, ofs;
4979   int i;
4980   char buf[50];
4981 
4982   printf("testing _tanltPiDiv4\n");
4983 
4984   float_create(&x);
4985   float_create(&tmp);
4986   float_create(&max);
4987   float_create(&step);
4988   float_create(&ofs);
4989 
4990   printf("verifying function results:\n");
4991   float_setzero(&x);
4992   _tanltPiDiv4(&x, 100);
4993   if(!float_iszero(&x))
4994   {
4995     printf("FAILED for x==0\n");
4996     return 0;
4997   }
4998   float_setasciiz(&x, "-0.5");
4999   float_setasciiz(&tmp, "-.54630248984379051325517946578028538329755"
5000                         "1720179791246164091385932907510518025815715"
5001                         "1806482706562185891048626002641142654932300911684");
5002   _tanltPiDiv4(&x, 100);
5003   if (!_cmprelerror(&tmp, &x, -99))
5004   {
5005     printf("FAILED for x==-0.5\n");
5006     return 0;
5007   }
5008 
5009   printf("testing error limit:\n");
5010   float_setzero(&max);
5011   float_setasciiz(&step, "0.005");
5012   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
5013          "24672389823467828246764829833467849839838778485784386584539"
5014          "85343784568643548923998439823432792346");
5015   for(i = 0; ++i < 158;)
5016   {
5017     float_muli(&tmp, &step, i, EXACT);
5018     float_add(&x, &tmp, &ofs, EXACT);
5019     float_copy(&tmp, &x, EXACT);
5020     _tanltPiDiv4(&x, 100);
5021     _tanltPiDiv4(&tmp, 110);
5022     _relerror(&x, &tmp);
5023     if (float_cmp(&x, &max) > 0)
5024     {
5025       float_copy(&max, &x, EXACT);
5026       if (float_getexponent(&x) >= -99)
5027       {
5028         printf("exceeding error in test case %d: ", i);
5029         float_getscientific(buf, 50, &max);
5030         printf("%s\n", buf);
5031         return 0;
5032       }
5033     }
5034   }
5035   float_getscientific(buf, 50, &max);
5036   printf("max error _tanltPiDiv4: %s\n", buf);
5037 
5038   float_free(&tmp);
5039   float_free(&x);
5040   float_free(&max);
5041   float_free(&step);
5042   float_free(&ofs);
5043   return 1;
5044 }
5045 
test_cos()5046 static int test_cos()
5047 {
5048   floatstruct x, tmp, max, step, ofs;
5049   int i;
5050   char buf[50];
5051 
5052   printf("testing _cos\n");
5053 
5054   float_create(&x);
5055   float_create(&tmp);
5056   float_create(&max);
5057   float_create(&step);
5058   float_create(&ofs);
5059 
5060   printf("verifying function results:\n");
5061   float_setzero(&x);
5062   _cos(&x, 100);
5063   if(float_cmp(&x, &c1)!=0)
5064   {
5065     printf("FAILED for x==0\n");
5066     return 0;
5067   }
5068   float_setasciiz(&step, "0.1");
5069   for (i = 0; ++i < 15;)
5070   {
5071     float_muli(&x, &step, i, EXACT);
5072     float_add(&tmp, &x, &x, EXACT);
5073     _cos(&x, 100);
5074     _cos(&tmp, 100);
5075     float_mul(&x, &x, &x, 110);
5076     float_add(&x, &x, &x, EXACT);
5077     float_sub(&x, &x, &c1, EXACT);
5078     if (!_cmprelerror(&tmp, &x, -95))
5079     {
5080       printf("FAILED for testcase %d\n", i);
5081       return 0;
5082     }
5083   }
5084 
5085   printf("testing error limit:\n");
5086   float_setzero(&max);
5087   float_setasciiz(&step, "0.05");
5088   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
5089          "24672389823467828246764829833467849839838778485784386584539"
5090          "85343784568643548923998439823432792346");
5091   for(i = -63; ++i < 63;)
5092   {
5093     float_muli(&tmp, &step, i, EXACT);
5094     float_add(&x, &tmp, &ofs, EXACT);
5095     float_copy(&tmp, &x, EXACT);
5096     _cos(&x, 100);
5097     _cos(&tmp, 110);
5098     _relerror(&x, &tmp);
5099     if (float_cmp(&x, &max) > 0)
5100     {
5101       float_copy(&max, &x, EXACT);
5102       if (float_getexponent(&x) >= -99)
5103       {
5104         printf("exceeding error in test case %d: ", i);
5105         float_getscientific(buf, 50, &max);
5106         printf("%s\n", buf);
5107         return 0;
5108       }
5109     }
5110   }
5111   float_getscientific(buf, 50, &max);
5112   printf("max error _cos: %s\n", buf);
5113 
5114   float_free(&tmp);
5115   float_free(&x);
5116   float_free(&max);
5117   float_free(&step);
5118   float_free(&ofs);
5119   return 1;
5120 }
5121 
test_sin()5122 static int test_sin()
5123 {
5124   floatstruct x, tmp, max, step, ofs;
5125   int i;
5126 
5127   printf("testing _sin\n");
5128 
5129   float_create(&x);
5130   float_create(&tmp);
5131   float_create(&max);
5132   float_create(&step);
5133   float_create(&ofs);
5134 
5135   printf("verifying function results:\n");
5136   float_setzero(&x);
5137   _sin(&x, 100);
5138   if(!float_iszero(&x))
5139   {
5140     printf("FAILED for x==0\n");
5141     return 0;
5142   }
5143   float_setasciiz(&step, "0.1");
5144   for (i = 0; ++i < 32;)
5145   {
5146     float_muli(&x, &step, i, EXACT);
5147     float_sub(&tmp, &x, &cPiDiv2, 110);
5148     _sin(&x, 100);
5149     _cos(&tmp, 100);
5150     if (!_cmprelerror(&tmp, &x, -95))
5151     {
5152       printf("FAILED for testcase %d\n", i);
5153       return 0;
5154     }
5155   }
5156 
5157   float_setasciiz(&step, "0.5");
5158   for (i = -7; ++i < 0;)
5159   {
5160     float_muli(&x, &step, i, EXACT);
5161     float_copy(&tmp, &x, EXACT);
5162     float_abs(&tmp);
5163     _sin(&x, 100);
5164     _sin(&tmp, 100);
5165     float_neg(&tmp);
5166     if (!_cmprelerror(&tmp, &x, -95))
5167     {
5168       printf("FAILED for testcase %d\n", i);
5169       return 0;
5170     }
5171   }
5172   float_free(&tmp);
5173   float_free(&x);
5174   float_free(&max);
5175   float_free(&step);
5176   float_free(&ofs);
5177   return 1;
5178 }
5179 
test_tan()5180 static int test_tan()
5181 {
5182   floatstruct x, tmp, max, step, ofs;
5183   int i;
5184   char buf[50];
5185 
5186   printf("testing _tan\n");
5187 
5188   float_create(&x);
5189   float_create(&tmp);
5190   float_create(&max);
5191   float_create(&step);
5192   float_create(&ofs);
5193 
5194   printf("verifying function results:\n");
5195   float_setzero(&x);
5196   _tan(&x, 100);
5197   if(!float_iszero(&x))
5198   {
5199     printf("FAILED for x==0\n");
5200     return 0;
5201   }
5202   float_setasciiz(&step, "0.1");
5203   for (i = -32; ++i < 32;)
5204   {
5205     if (i == 0)
5206       continue;
5207     float_muli(&x, &step, i, EXACT);
5208     float_copy(&tmp, &x, EXACT);
5209     float_copy(&ofs, &x, EXACT);
5210     _sin(&x, 100);
5211     _cos(&tmp, 100);
5212     float_div(&tmp, &x, &tmp, 110);
5213     _tan(&ofs, 100);
5214     if (!_cmprelerror(&tmp, &ofs, -95))
5215     {
5216       printf("FAILED for testcase %d\n", i);
5217       return 0;
5218     }
5219   }
5220 
5221   printf("testing error limit:\n");
5222   float_setzero(&max);
5223   float_setasciiz(&step, "0.05");
5224   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
5225          "24672389823467828246764829833467849839838778485784386584539"
5226          "85343784568643548923998439823432792346");
5227   for(i = -63; ++i < 63;)
5228   {
5229     float_muli(&tmp, &step, i, EXACT);
5230     float_add(&x, &tmp, &ofs, EXACT);
5231     float_copy(&tmp, &x, EXACT);
5232     _tan(&x, 100);
5233     _tan(&tmp, 110);
5234     _relerror(&x, &tmp);
5235     if (float_cmp(&x, &max) > 0)
5236     {
5237       float_copy(&max, &x, EXACT);
5238       if (float_getexponent(&x) >= -99)
5239       {
5240         printf("exceeding error in test case %d: ", i);
5241         float_getscientific(buf, 50, &max);
5242         printf("%s\n", buf);
5243         return 0;
5244       }
5245     }
5246   }
5247   float_getscientific(buf, 50, &max);
5248   printf("max error _tan: %s\n", buf);
5249 
5250   return 1;
5251 }
5252 
tc_floatnum2longint(char * value,int lg,unsigned x0,unsigned x1,unsigned x2)5253 static int tc_floatnum2longint(char* value,
5254   int lg, unsigned x0, unsigned x1, unsigned x2)
5255 {
5256   floatstruct x;
5257   t_longint longint;
5258 
5259   float_create(&x);
5260   float_setasciiz(&x, value);
5261   _floatnum2longint(&longint, &x);
5262   float_free(&x);
5263   return lg == longint.length && (lg == 0 || x0 == longint.value[0])
5264          && (lg < 32 || x1 == longint.value[1])
5265          && (lg < 64 || x2 == longint.value[2]);
5266 }
5267 
test_floatnum2longint()5268 static int test_floatnum2longint()
5269 {
5270   /* depends on wordsize!! */
5271   printf("testing floatnum2longint\n");
5272 
5273   if (!tc_floatnum2longint("0", 0, 0, 0, 0)) return 0;
5274   if (!tc_floatnum2longint("1", 1, 1, 0, 0)) return 0;
5275   if (!tc_floatnum2longint("1234567890", 1, 1234567890, 0, 0)) return 0;
5276   if (!tc_floatnum2longint("8589934592", 2, 0, 2, 0)) return 0;
5277   return 1;
5278 }
5279 
tc_longint2floatnum(unsigned x0,unsigned x1,unsigned x2,int lg,char * value)5280 static int tc_longint2floatnum(unsigned x0, unsigned x1, unsigned x2, int lg, char* value)
5281 {
5282   /* depends on wordsize!! */
5283   floatstruct x, y;
5284   t_longint l;
5285   int i;
5286 
5287   float_create(&x);
5288   float_create(&y);
5289 
5290   for (i = 0; i < UARRAYLG; ++i)
5291     l.value[i] = 0;
5292   l.value[0] = x0;
5293   l.value[1] = x1;
5294   l.value[2] = x2;
5295   l.length = lg;
5296   float_setasciiz(&y, value);
5297   _longint2floatnum(&x, &l);
5298   if (float_cmp(&x, &y) != 0)
5299   {
5300     printf("conversion FAILED");
5301     return 0;
5302   }
5303   float_free(&x);
5304   float_free(&y);
5305   return 1;
5306 }
5307 
test_longint2floatnum()5308 static int test_longint2floatnum()
5309 {
5310   printf("testing longint2floatnum\n");
5311   if (!tc_longint2floatnum(0, 0, 0, 0, "0")) return 0;
5312   if (!tc_longint2floatnum(1, 0, 0, 1, "1")) return 0;
5313   if (!tc_longint2floatnum(2000000000, 0, 0, 1, "2000000000")) return 0;
5314   if (!tc_longint2floatnum(0, 2, 0, 2, "8589934592")) return 0;
5315   if (!tc_longint2floatnum(1000000, 2, 0, 2, "8590934592")) return 0;
5316   return 1;
5317 }
5318 
tc_raiseposi(char * base,unsigned exponent)5319 static int tc_raiseposi(char* base, unsigned exponent)
5320 {
5321   floatstruct x, y;
5322   int expx, result;
5323 
5324   float_create(&x);
5325   float_create(&y);
5326   float_setasciiz(&x, base);
5327   float_copy(&y, &x, EXACT);
5328   float_abs(&y);
5329   float_lg(&y, 100);
5330   _raiseposi(&x, &expx, exponent, 100);
5331   float_abs(&x);
5332   float_lg(&x, 199);
5333   float_addi(&x, &x, expx, 100);
5334   float_divi(&x, &x, exponent, 100);
5335   result = _cmprelerror(&x, &y, 95);
5336   float_free(&x);
5337   float_free(&y);
5338   return result;
5339 }
5340 
test_raiseposi()5341 static int test_raiseposi()
5342 {
5343   floatstruct x, tmp, max, step, ofs;
5344   int expx;
5345   int i, j;
5346   char buf[50];
5347 
5348   printf("testing _raiseposi\n");
5349 
5350   float_create(&x);
5351   float_create(&tmp);
5352   float_create(&max);
5353   float_create(&step);
5354   float_create(&ofs);
5355 
5356   if (!tc_raiseposi("1", 1)) return 0;
5357   if (!tc_raiseposi("2", 1)) return 0;
5358   if (!tc_raiseposi("2", 2)) return 0;
5359   if (!tc_raiseposi("2", 3)) return 0;
5360   float_setinteger(&x, -1);
5361   _raiseposi(&x, &expx, 3, 100);
5362   if (float_cmp(&x, &cMinus1) != 0 || expx != 0)
5363   {
5364     printf("test case -1 ^ 3 FAILED");
5365     return 0;
5366   }
5367   _raiseposi(&x, &expx, 2, 100);
5368   if (float_cmp(&x, &c1) != 0 || expx != 0)
5369   {
5370     printf("test case -1 ^ 2 FAILED");
5371     return 0;
5372   }
5373   printf("testing error limit:\n");
5374   float_setzero(&max);
5375   float_setasciiz(&step, "1");
5376   float_setasciiz(&ofs, "1.000147436738983647399324678823992433673"
5377          "24672389823467828246764829833467849839838778485784386584539"
5378          "85343784568643548923998439823432792346");
5379   for (j = 0; j++ < 30;)
5380     for(i = 0; ++i < 10;)
5381     {
5382       float_muli(&tmp, &step, i, EXACT);
5383       float_add(&x, &tmp, &ofs, EXACT);
5384       float_copy(&tmp, &x, EXACT);
5385       _raiseposi(&x, &expx, (1 << j)-1, 100);
5386       _raiseposi(&tmp, &expx, (1 << j)-1, 110);
5387       _relerror(&x, &tmp);
5388       if (float_cmp(&x, &max) > 0)
5389       {
5390         float_copy(&max, &x, EXACT);
5391         if (float_getexponent(&x) >= -99)
5392         {
5393           printf("exceeding error in test case %d: ", i);
5394           float_getscientific(buf, 50, &max);
5395           printf("%s\n", buf);
5396           return 0;
5397         }
5398       }
5399     }
5400   float_getscientific(buf, 50, &max);
5401   printf("max error _raiseposi: %s\n", buf);
5402 
5403   float_free(&tmp);
5404   float_free(&x);
5405   float_free(&max);
5406   float_free(&step);
5407   float_free(&ofs);
5408   return 1;
5409 }
5410 
test_raisei()5411 static int test_raisei()
5412 {
5413   floatstruct x, y;
5414 
5415   printf ("testing _raisei\n");
5416   float_create(&x);
5417   float_create(&y);
5418   float_copy(&x, &c1, EXACT);
5419   _raisei(&x, 0, 100);
5420   if (float_cmp(&x, &c1) != 0)
5421   {
5422     printf("test case 1^0 FAILED\n");
5423     return 0;
5424   }
5425   _raisei(&x, 1, 100);
5426   if (float_cmp(&x, &c1) != 0)
5427   {
5428     printf("test case 1^1 FAILED\n");
5429     return 0;
5430   }
5431   _raisei(&x, 100, 100);
5432   if (float_cmp(&x, &c1) != 0)
5433   {
5434     printf("test case 1^100 FAILED\n");
5435     return 0;
5436   }
5437   float_copy(&x, &c2, EXACT);
5438   _raisei(&x, 0, 100);
5439   if (float_cmp(&x, &c1) != 0)
5440   {
5441     printf("test case 2^0 FAILED\n");
5442     return 0;
5443   }
5444   float_copy(&x, &c2, EXACT);
5445   _raisei(&x, 1, 100);
5446   if (float_cmp(&x, &c2) != 0)
5447   {
5448     printf("test case 2^1 FAILED\n");
5449     return 0;
5450   }
5451   float_setinteger(&y, 4);
5452   _raisei(&x, 2, 100);
5453   if (float_cmp(&x, &y) != 0)
5454   {
5455     printf("test case 2^2 FAILED\n");
5456     return 0;
5457   }
5458   float_copy(&x, &c2, EXACT);
5459   _raisei(&x, -1, 100);
5460   if (float_cmp(&x, &c1Div2) != 0)
5461   {
5462     printf("test case 2^-1 FAILED\n");
5463     return 0;
5464   }
5465 
5466   float_free(&y);
5467   float_free(&x);
5468   return 1;
5469 }
5470 
test_binetasymptotic()5471 static int test_binetasymptotic()
5472 {
5473   floatstruct x, y, tmp;
5474   int i;
5475 
5476   printf("testing lngammaseries\n");
5477 
5478   float_create(&x);
5479   float_create(&y);
5480   float_create(&tmp);
5481   printf("verifying result\n");
5482   float_setinteger(&tmp, 77);
5483   float_ln(&tmp, 110);
5484   float_setasciiz(&y, "76.5");
5485   float_mul(&tmp, &tmp, &y, 110);
5486   float_setinteger(&y, 2);
5487   for (i = 2; ++i < 77;)
5488     float_muli(&y, &y, i, EXACT);
5489   float_ln(&y, 110);
5490   float_sub(&y, &y, &tmp, 110);
5491   float_addi(&y, &y, 77, 110);
5492   float_sub(&y, &y, &cLnSqrt2PiMinusHalf, 110);
5493   float_sub(&y, &y, &c1Div2, 110);
5494   float_setinteger(&x, 77);
5495   binetasymptotic(&x, 100);
5496   if (!_cmprelerror(&y, &x, -95))
5497   {
5498     printf("verification FAILED\n");
5499     return 0;
5500   }
5501   float_free(&x);
5502   float_free(&y);
5503   float_free(&tmp);
5504   return 1;
5505 }
5506 
tc_pochhammer(char * x,char * n,char * result)5507 static int tc_pochhammer(char* x, char* n, char* result)
5508 {
5509   floatstruct fx, fn, fr;
5510 
5511   float_create(&fx);
5512   float_create(&fn);
5513   float_create(&fr);
5514   float_setasciiz(&fx, x);
5515   float_setasciiz(&fn, n);
5516   float_setasciiz(&fr, result);
5517   float_pochhammer(&fx, &fn, 100);
5518   if (float_isnan(&fr))
5519     return float_isnan(&fx);
5520   if (!_cmprelerror(&fr, &fx, -95))
5521   {
5522     printf("verification FAILED\n");
5523     return 0;
5524   }
5525   return 1;
5526 }
5527 
test_pochhammer()5528 static int test_pochhammer()
5529 {
5530   printf("testing _pochhammer\n");
5531   printf("verifying results\n");
5532   if (!tc_pochhammer("0", "0", "1")) return 0;
5533   if (!tc_pochhammer("1", "0", "1")) return 0;
5534   if (!tc_pochhammer("-1", "0", "1")) return 0;
5535   if (!tc_pochhammer("1e100000", "0", "1")) return 0;
5536   if (!tc_pochhammer("-1e100000", "0", "1")) return 0;
5537   if (!tc_pochhammer("0.5", "0", "1")) return 0;
5538   if (!tc_pochhammer("-0.5", "0", "1")) return 0;
5539   if (!tc_pochhammer("0", "1", "0")) return 0;
5540   if (!tc_pochhammer("1", "1", "1")) return 0;
5541   if (!tc_pochhammer("-1", "1", "-1")) return 0;
5542   if (!tc_pochhammer("1e100000", "1", "1e100000")) return 0;
5543   if (!tc_pochhammer("-1e100000", "1", "-1e100000")) return 0;
5544   if (!tc_pochhammer("0.5", "1", "0.5")) return 0;
5545   if (!tc_pochhammer("-0.5", "1", "-0.5")) return 0;
5546   if (!tc_pochhammer("0", "2", "0")) return 0;
5547   if (!tc_pochhammer("1", "2", "2")) return 0;
5548   if (!tc_pochhammer("-1", "2", "0")) return 0;
5549   if (!tc_pochhammer("1e100000", "2", "1e200000")) return 0;
5550   if (!tc_pochhammer("-1e100000", "2", "1e200000")) return 0;
5551   if (!tc_pochhammer("0.5", "2", "0.75")) return 0;
5552   if (!tc_pochhammer("-0.5", "2", "-0.25")) return 0;
5553   if (!tc_pochhammer("1", "100", "93326215443944152681699238856266700490715968264381621468592963895217"
5554        "59999322991560894146397615651828625369792082722375825118521091686400"
5555        "0000000000000000000000")) return 0;
5556   if (!tc_pochhammer("-100", "101", "0")) return 0;
5557   if (!tc_pochhammer("-100", "100", "93326215443944152681699238856266700490715968264381621468592963895217"
5558        "59999322991560894146397615651828625369792082722375825118521091686400"
5559        "0000000000000000000000")) return 0;
5560   if (!tc_pochhammer("1", "-1", "NaN")) return 0;
5561   if (!tc_pochhammer("2", "-1", "1")) return 0;
5562   if (!tc_pochhammer("2", "-2", "NaN")) return 0;
5563   if (!tc_pochhammer("1.5", "-1", "2")) return 0;
5564   if (!tc_pochhammer("1.5", "-2", "-4")) return 0;
5565   if (!tc_pochhammer("1.5", "-100", "-.000000000000000000000000000000000000000000000000000000000000000000"
5566                      "00000000000000000000000000000000000000000000000000000000000000000000"
5567                      "00000000000000000000378414024807910640737099845525006763221785165860"
5568                      "06641218189552393913245454474853055919575212143764296945522753626016"
5569                      "300639832411419246985800884362")) return 0;
5570   if (!tc_pochhammer("-1.5", "100", "40242764267707289912333641217950774848709656376758843494819950464847"
5571                      "04420564703857828107982141126998570896720926829585700250010032188267"
5572                      "20546901916750645.18900647214084211566623156559209401240552373723543")) return 0;
5573   if (!tc_pochhammer("-3", "-1", "-0.25")) return 0;
5574   if (!tc_pochhammer("-1e100000", "-1", "-1e-100000")) return 0;
5575   if (!tc_pochhammer("-2.2", "1.3", "4.793948981105061902495028514824576929486499142574590370996037700670"
5576                      "07956370445687178188113235399766021571905874962934089400569549735499"
5577                      "47062783690929661636680480933415006255499710782394427770555172981506")) return 0;
5578   return 1;
5579 }
5580 
test_lngamma()5581 static int test_lngamma()
5582 {
5583   floatstruct x, tmp, max, step, ofs;
5584   int i;
5585   char buf[50];
5586 
5587   printf("testing _lngamma\n");
5588   float_create(&x);
5589   float_create(&tmp);
5590   float_create(&max);
5591   float_create(&step);
5592   float_create(&ofs);
5593 
5594   printf("verifying results\n");
5595   float_copy(&x, &c3, EXACT);
5596   _lngamma(&x, 100);
5597   if(!_cmprelerror(&x, &cLn2, -95))
5598   {
5599     printf("verification FAILED\n");
5600     return 0;
5601   }
5602   printf("testing error limit:\n");
5603   float_setzero(&max);
5604   float_setasciiz(&step, "0.05");
5605   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
5606          "24672389823467828246764829833467849839838778485784386584539"
5607          "85343784568643548923998439823432792346");
5608   for(i = 100; ++i < 200;)
5609   {
5610     float_muli(&tmp, &step, i, EXACT);
5611     float_add(&x, &tmp, &ofs, EXACT);
5612     float_copy(&tmp, &x, EXACT);
5613     _lngamma(&x, 100);
5614     _lngamma(&tmp, 110);
5615     _relerror(&x, &tmp);
5616     if (float_cmp(&x, &max) > 0)
5617     {
5618       float_copy(&max, &x, EXACT);
5619       if (float_getexponent(&x) >= -99)
5620       {
5621         printf("exceeding error in test case %d: ", i);
5622         float_getscientific(buf, 50, &max);
5623         printf("%s\n", buf);
5624         return 0;
5625       }
5626     }
5627   }
5628   float_getscientific(buf, 50, &max);
5629   printf("max error _lngamma: %s\n", buf);
5630   float_free(&tmp);
5631   float_free(&x);
5632   float_free(&max);
5633   float_free(&step);
5634   float_free(&ofs);
5635   return 1;
5636 }
5637 
test_gamma()5638 static int test_gamma()
5639 {
5640   floatstruct x, tmp, max, step, ofs;
5641   int i;
5642   char buf[50];
5643 
5644   printf("testing _gamma\n");
5645 
5646   float_create(&x);
5647   float_create(&tmp);
5648   float_create(&max);
5649   float_create(&step);
5650   float_create(&ofs);
5651   printf("verifying results\n");
5652   float_setasciiz(&x, "0.2");
5653   float_setasciiz(&tmp, "4.590843711998803053204758275929152003434109998293403"
5654                         "01778885313623003927310644499897403940828778507456912");
5655   _gamma(&x, 100);
5656   if(!_cmprelerror(&x, &tmp, -95))
5657   {
5658     printf("verification FAILED\n");
5659     return 0;
5660   }
5661   float_setasciiz(&x, "-30.2");
5662   float_setasciiz(&tmp, "-1.0165368282364803216788184978362164979757349922035594"
5663                         "1791712115025420329582124053302476303836291973429411315e-32");
5664   _gamma(&x, 100);
5665   if(!_cmprelerror(&x, &tmp, -95))
5666   {
5667     printf("verification FAILED\n");
5668     return 0;
5669   }
5670   float_setasciiz(&x, "-1.5");
5671   float_setasciiz(&tmp, "0.75");
5672   float_div(&tmp, &cSqrtPi, &tmp, 110);
5673   _gamma(&x, 100);
5674   if(!_cmprelerror(&x, &tmp, -95))
5675   {
5676     printf("verification FAILED\n");
5677     return 0;
5678   }
5679   float_setasciiz(&x, "10");
5680   float_setasciiz(&tmp, "362880");
5681   _gamma(&x, 100);
5682   if(!_cmprelerror(&x, &tmp, -95))
5683   {
5684     printf("verification FAILED\n");
5685     return 0;
5686   }
5687   printf("testing error limit:\n");
5688   float_setzero(&max);
5689   float_setasciiz(&step, "0.05");
5690   float_setasciiz(&ofs, "0.000147436738983647399324678823992433673"
5691          "24672389823467828246764829833467849839838778485784386584539"
5692          "85343784568643548923998439823432792346");
5693   for(i = 100; ++i < 200;)
5694   {
5695     float_muli(&tmp, &step, i, EXACT);
5696     float_add(&x, &tmp, &ofs, EXACT);
5697     float_copy(&tmp, &x, EXACT);
5698     _gamma(&x, 100);
5699     _gamma(&tmp, 110);
5700     _relerror(&x, &tmp);
5701     if (float_cmp(&x, &max) > 0)
5702     {
5703       float_copy(&max, &x, EXACT);
5704       if (float_getexponent(&x) >= -99)
5705       {
5706         printf("exceeding error in test case %d: ", i);
5707         float_getscientific(buf, 50, &max);
5708         printf("%s\n", buf);
5709         return 0;
5710       }
5711     }
5712   }
5713   printf("testing asymptotic series of gamma:\n");
5714   for(i = 0; ++i < 100;)
5715   {
5716     float_setasciiz(&x, "1.01");
5717     printf("testing precision %d: ", i);
5718     _gamma(&x, i);
5719     printf("asymptotic series converging\n");
5720   }
5721   float_getscientific(buf, 50, &max);
5722   printf("max error _gamma: %s\n", buf);
5723   float_free(&tmp);
5724   float_free(&x);
5725   float_free(&max);
5726   float_free(&step);
5727   float_free(&ofs);
5728   return 1;
5729 }
5730 
test_gammaint()5731 static int test_gammaint()
5732 {
5733   floatstruct x, y;
5734 
5735   printf("testing _gammaint\n");
5736 
5737   float_create(&x);
5738   float_create(&y);
5739   printf("verifying results\n");
5740   float_setinteger(&x, 1);
5741   float_setinteger(&y, 1);
5742   _gammaint(&x, 100);
5743   if (float_cmp(&x, &y) != 0)
5744   {
5745     printf("verification FAILED\n");
5746     return 0;
5747   }
5748   float_setinteger(&x, 2);
5749   float_setinteger(&y, 1);
5750   _gammaint(&x, 100);
5751   if (float_cmp(&x, &y) != 0)
5752   {
5753     printf("verification FAILED\n");
5754     return 0;
5755   }
5756   float_setinteger(&x, 3);
5757   float_setinteger(&y, 2);
5758   _gammaint(&x, 100);
5759   if (float_cmp(&x, &y) != 0)
5760   {
5761     printf("verification FAILED\n");
5762     return 0;
5763   }
5764 
5765   float_free(&x);
5766   float_free(&y);
5767   return 1;
5768 }
5769 
tc_gamma0_5(char * value)5770 static int tc_gamma0_5(char* value)
5771 {
5772   floatstruct x, y;
5773 
5774   float_create(&x);
5775   float_create(&y);
5776   float_setasciiz(&x, value);
5777   float_copy(&y, &x, EXACT);
5778   _gamma0_5(&x, 100);
5779   _gamma(&y, 100);
5780   if (!_cmprelerror(&x, &y, -95))
5781   {
5782     printf("verification FAILED\n");
5783     return 0;
5784   }
5785   float_free(&x);
5786   float_free(&y);
5787   return 1;
5788 }
5789 
test_gamma0_5()5790 static int test_gamma0_5()
5791 {
5792   printf("testing _gamma0_5\n");
5793 
5794   printf("verifying results\n");
5795   if (!tc_gamma0_5(".5")) return 0;
5796   if (!tc_gamma0_5("-.5")) return 0;
5797   if (!tc_gamma0_5("1.5")) return 0;
5798   if (!tc_gamma0_5("-1.5")) return 0;
5799   if (!tc_gamma0_5("-30.5")) return 0;
5800   if (!tc_gamma0_5("30.5")) return 0;
5801   return 1;
5802 }
5803 
tc_floatnum2logic(char * value,unsigned x0,unsigned x1,unsigned x2)5804 static int tc_floatnum2logic(char* value, unsigned x0, unsigned x1, unsigned x2)
5805 {
5806   floatstruct x;
5807   t_longint r;
5808 
5809   float_create(&x);
5810   float_setasciiz(&x, value);
5811   _floatnum2logic(&r, &x);
5812   float_free(&x);
5813   return r.value[0] == x0 && r.value[1] == x1 && r.value[2] == x2;
5814 }
5815 
test_floatnum2logic()5816 static int test_floatnum2logic()
5817 {
5818   /* based on the size of unsigned */
5819   printf("testing _floatnum2logic\n");
5820 
5821   if(!tc_floatnum2logic("0", 0, 0, 0)) return 0;
5822   if(!tc_floatnum2logic("1", 1, 0, 0)) return 0;
5823   if(!tc_floatnum2logic("-1", ~0, ~0, ~0)) return 0;
5824   if(!tc_floatnum2logic("-2147483648", ~2147483647, ~0, ~0)) return 0;
5825   if(!tc_floatnum2logic("8589934592", 0, 2, 0)) return 0;
5826   return 1;
5827 }
5828 
tc_logic2floatnum(char * value)5829 static int tc_logic2floatnum(char* value)
5830 {
5831   t_longint l;
5832   floatstruct x, y;
5833 
5834   float_create(&x);
5835   float_create(&y);
5836   float_setasciiz(&x, value);
5837   _floatnum2logic(&l, &x);
5838   _logic2floatnum(&y, &l);
5839   if (float_cmp(&x, &y) != 0)
5840   {
5841     printf("test case %s FAILED\n", value);
5842     return 0;
5843   }
5844   float_free(&x);
5845   float_free(&y);
5846   return 1;
5847 }
5848 
test_logic2floatnum()5849 static int test_logic2floatnum()
5850 {
5851   printf("testing _logic2floatnum\n");
5852 
5853   if(!tc_logic2floatnum("0")) return 0;
5854   if(!tc_logic2floatnum("1")) return 0;
5855   if(!tc_logic2floatnum("-1")) return 0;
5856   if(!tc_logic2floatnum("-2147483648")) return 0;
5857   if(!tc_logic2floatnum("-2147483649")) return 0;
5858   if(!tc_logic2floatnum("4294967295")) return 0;
5859   if(!tc_logic2floatnum("-4294967296")) return 0;
5860   if(!tc_logic2floatnum("8589934592")) return 0;
5861   return 1;
5862 }
5863 
tc_not(char * value,char * result)5864 static int tc_not(char* value, char* result)
5865 {
5866   floatstruct x, y;
5867 
5868   float_create(&x);
5869   float_create(&y);
5870   float_setasciiz(&x, value);
5871   float_setasciiz(&y, result);
5872   float_not(&x);
5873   if (float_cmp(&x, &y) != 0) return 0;
5874   float_free(&x);
5875   float_free(&y);
5876   return 1;
5877 }
5878 
test_not()5879 static int test_not()
5880 {
5881   printf("testing float_not\n");
5882 
5883   if (!tc_not("0", "-1")) return 0;
5884   if (!tc_not("1", "-2")) return 0;
5885   if (!tc_not("-1", "0")) return 0;
5886   if (!tc_not("-2", "1")) return 0;
5887   return 1;
5888 }
5889 
test_and()5890 static int test_and()
5891 {
5892   floatstruct x, y;
5893 
5894   printf("testing float_and\n");
5895 
5896   float_create(&x);
5897   float_create(&y);
5898   float_setasciiz(&x, "5");
5899   float_setasciiz(&y, "6");
5900   float_and(&x, &x, &y);
5901   float_setasciiz(&y, "4");
5902   if (float_cmp(&x, &y) != 0) return 0;
5903   float_free(&x);
5904   float_free(&y);
5905   return 1;
5906 }
5907 
test_or()5908 static int test_or()
5909 {
5910   floatstruct x, y;
5911 
5912   printf("testing float_or\n");
5913 
5914   float_create(&x);
5915   float_create(&y);
5916   float_setasciiz(&x, "5");
5917   float_setasciiz(&y, "6");
5918   float_or(&x, &x, &y);
5919   float_setasciiz(&y, "7");
5920   if (float_cmp(&x, &y) != 0) return 0;
5921   float_free(&x);
5922   float_free(&y);
5923   return 1;
5924 }
5925 
test_xor()5926 static int test_xor()
5927 {
5928   floatstruct x, y;
5929 
5930   printf("testing float_xor\n");
5931 
5932   float_create(&x);
5933   float_create(&y);
5934   float_setasciiz(&x, "5");
5935   float_setasciiz(&y, "6");
5936   float_xor(&x, &x, &y);
5937   float_setasciiz(&y, "3");
5938   if (float_cmp(&x, &y) != 0) return 0;
5939   float_free(&x);
5940   float_free(&y);
5941   return 1;
5942 }
5943 
5944 #define tc_shl(value, shift, result)  \
5945   _tc_shl(__FILE__,__LINE__, #value"/"#shift, value, shift, result)
5946 
_tc_shl(const char * file,int line,char * msg,char * value,char * shift,char * result)5947 static void _tc_shl(const char* file, int line, char* msg, char* value, char* shift, char* result)
5948 {
5949   floatstruct x, y;
5950 
5951   float_create(&x);
5952   float_create(&y);
5953 
5954   float_setasciiz(&x, value);
5955   float_setasciiz(&y, shift);
5956   float_shl(&x, &x, &y);
5957   float_setasciiz(&y, result);
5958 
5959   DisplayErrorOnFloatMismatch(file, line, msg, &x, &y, &g_failed_tests, &g_new_failed_tests, 0);
5960 
5961   float_free(&x);
5962   float_free(&y);
5963 }
5964 
test_shl()5965 static int test_shl()
5966 {
5967   printf("testing float_shl\n");
5968 
5969   tc_shl("0", "0", "0");
5970   tc_shl("-1", "0", "-1");
5971   tc_shl("1", "1", "2");
5972   tc_shl("1", "32", "4294967296");
5973   tc_shl("1", "64", "18446744073709551616");
5974   tc_shl("1", "96", "0");
5975   tc_shl("1", "95", "-39614081257132168796771975168");
5976   tc_shl("1", "1000", "0");
5977   tc_shl("4294967295", "1", "8589934590");
5978 
5979   return 1;
5980 }
5981 
tc_shr(char * value,char * shift,char * result)5982 static int tc_shr(char* value, char* shift, char* result)
5983 {
5984   floatstruct x, y;
5985 
5986   float_create(&x);
5987   float_create(&y);
5988 
5989   float_setasciiz(&x, value);
5990   float_setasciiz(&y, shift);
5991   float_shr(&x, &x, &y);
5992   float_setasciiz(&y, result);
5993 
5994   if(float_cmp(&x, &y) != 0) return 0;
5995 
5996   float_free(&x);
5997   float_free(&y);
5998   return 1;
5999 }
6000 
test_shr()6001 static int test_shr()
6002 {
6003   printf("testing float_shr\n");
6004 
6005   if (!tc_shr("0", "0", "0")) return 0;
6006   if (!tc_shr("1", "1", "0")) return 0;
6007   if (!tc_shr("2", "1", "1")) return 0;
6008   if (!tc_shr("4294967296", "32", "1")) return 0;
6009   if (!tc_shr("-1", "32", "-1")) return 0;
6010   if (!tc_shr("-4", "1", "-2")) return 0;
6011   if (!tc_shr("-39614081257132168796771975168", "94", "-2")) return 0;
6012   return 1;
6013 }
6014 
_tc_out(const char * file,int line,char * msg,char * value,int digits,char base,char mode,char * result)6015 static void _tc_out(const char* file, int line, char* msg, char* value, int digits, char base, char mode, char* result)
6016 {
6017   char intbuf[150];
6018   char fracbuf[150];
6019   char buffer[350];
6020   t_otokens tokens;
6021   floatstruct x;
6022 
6023   ++g_total_tests;
6024 
6025   float_create(&x);
6026   float_setasciiz(&x, value);
6027   tokens.intpart.sz = sizeof(intbuf);
6028   tokens.intpart.buf = intbuf;
6029   tokens.fracpart.sz = 150;
6030   tokens.fracpart.buf = fracbuf;
6031   if (float_out(&tokens, &x, digits, base, mode) != Success) {
6032     if (result != NULL && *result != '\0') {
6033       DisplayErrorOnStrMismatch(file, line, msg, "ERROR", result, &g_failed_tests, &g_new_failed_tests, 0);
6034     }
6035     return;
6036   }
6037   cattokens(buffer, 350, &tokens, 0,
6038     IO_FLAG_SHOW_BASE + IO_FLAG_SHOW_EXPBASE + IO_FLAG_SUPPRESS_DOT
6039     + IO_FLAG_SUPPRESS_LDG_ZERO);
6040   float_free(&x);
6041   DisplayErrorOnStrMismatch(file, line, msg, buffer, result, &g_failed_tests, &g_new_failed_tests, 0);
6042 }
6043 
test_out()6044 static int test_out()
6045 {
6046   t_ioparams iop[4] = {
6047     // base, expbase, dot, basetag, expbegin, expend, cmpltag, maxdigits
6048     {10, 10, '.', "0d", "(", ")", "", 70},
6049     {16, 10, '.', "0x", "(", ")", "sF", 70},
6050     {2, 10, '.', "0b", "(", ")", "s1", 70},
6051     {8, 10, '.', "0o", "(", ")", "s7", 70}
6052   };
6053   t_ioparams saveiop[4];
6054   int i;
6055 
6056   // Use our own ioparams to make sure the results are the expected ones
6057   for (i = 0 ; i < sizeof(iop) / sizeof(t_ioparams) ; ++i) {
6058     saveiop[i] = *getioparams(iop[i].base);
6059     setioparams(&iop[i]);
6060   }
6061 
6062   printf("testing float_out\n");
6063 
6064   tc_out("NaN", 0, 10, IO_MODE_SCIENTIFIC, "NaN");
6065   tc_out("0", 0, IO_BASE_NAN, IO_MODE_SCIENTIFIC, "");
6066   tc_out("0", 0, IO_BASE_ZERO, IO_MODE_SCIENTIFIC, "");
6067   tc_out("1", 0, IO_BASE_NAN, IO_MODE_SCIENTIFIC, "");
6068   tc_out("0", 0, 5, IO_MODE_SCIENTIFIC, "");
6069   tc_out("0", 0, 10, -1, "");
6070   tc_out("0", 0, 10, IO_MODE_SCIENTIFIC, "0");
6071   tc_out("1", 0, 10, IO_MODE_SCIENTIFIC, "+0d1(+0d0)");
6072   tc_out("-1", 0, 10, IO_MODE_SCIENTIFIC, "-0d1(+0d0)");
6073   tc_out("1.000000002", 0, 10, IO_MODE_SCIENTIFIC, "+0d1(+0d0)");
6074   tc_out("1.0002", 1, 10, IO_MODE_SCIENTIFIC, "+0d1.0(+0d0)");
6075   tc_out("1.07", 1, 10, IO_MODE_SCIENTIFIC, "+0d1.1(+0d0)");
6076   tc_out("1.2", 1, 10, IO_MODE_SCIENTIFIC, "+0d1.2(+0d0)");
6077   tc_out("1.2", 2, 10, IO_MODE_SCIENTIFIC, "+0d1.20(+0d0)");
6078   tc_out("10", 0, 10, IO_MODE_SCIENTIFIC, "+0d1(+0d1)");
6079   tc_out("100", 0, 10, IO_MODE_SCIENTIFIC, "+0d1(+0d2)");
6080   tc_out("1e12345678", 0, 10, IO_MODE_SCIENTIFIC, "+0d1(+0d12345678)");
6081   tc_out("1.234e12345678", 0, 10, IO_MODE_SCIENTIFIC, "+0d1(+0d12345678)");
6082   tc_out("1.234e12345678", 1, 10, IO_MODE_SCIENTIFIC, "+0d1.2(+0d12345678)");
6083   tc_out("1.234e12345678", 3, 10, IO_MODE_SCIENTIFIC, "+0d1.234(+0d12345678)");
6084   tc_out("1.234e12345678", 4, 10, IO_MODE_SCIENTIFIC, "+0d1.2340(+0d12345678)");
6085   tc_out("0.1", 0, 10, IO_MODE_SCIENTIFIC, "+0d1(-0d1)");
6086   tc_out("1.234e-12345678", 0, 10, IO_MODE_SCIENTIFIC, "+0d1(-0d12345678)");
6087   tc_out("1.234e-12345678", 1, 10, IO_MODE_SCIENTIFIC, "+0d1.2(-0d12345678)");
6088   tc_out("1.234e-12345678", 3, 10, IO_MODE_SCIENTIFIC, "+0d1.234(-0d12345678)");
6089   tc_out("1.234e-12345678", 4, 10, IO_MODE_SCIENTIFIC, "+0d1.2340(-0d12345678)");
6090   tc_out("1", 0, 16, IO_MODE_SCIENTIFIC, "+0x1(+0d0)");
6091   tc_out("15", 0, 16, IO_MODE_SCIENTIFIC, "+0xF(+0d0)");
6092   tc_out("16", 0, 16, IO_MODE_SCIENTIFIC, "+0x1(+0d1)");
6093   tc_out("17", 0, 16, IO_MODE_SCIENTIFIC, "+0x1(+0d1)");
6094   tc_out("18", 1, 16, IO_MODE_SCIENTIFIC, "+0x1.2(+0d1)");
6095   tc_out("4096", 0, 16, IO_MODE_SCIENTIFIC, "+0x1(+0d3)");
6096   tc_out("6144", 0, 16, IO_MODE_SCIENTIFIC, "+0x2(+0d3)");
6097   tc_out("1099511627776", 0, 16, IO_MODE_SCIENTIFIC, "+0x1(+0d10)");
6098   tc_out("18446744073709551616", 0, 16, IO_MODE_SCIENTIFIC, "+0x1(+0d16)");
6099   tc_out("18446744073709551616", 15, 16, IO_MODE_SCIENTIFIC, "+0x1.000000000000000(+0d16)");
6100   tc_out("1.8", 0, 16, IO_MODE_SCIENTIFIC, "+0x2(+0d0)");
6101   tc_out("-1.5", 1, 16, IO_MODE_SCIENTIFIC, "-0x1.8(+0d0)");
6102   tc_out("0.5", 0, 16, IO_MODE_SCIENTIFIC, "+0x8(-0d1)");
6103   tc_out("0.25", 0, 16, IO_MODE_SCIENTIFIC, "+0x4(-0d1)");
6104   tc_out("0.125", 0, 16, IO_MODE_SCIENTIFIC, "+0x2(-0d1)");
6105   tc_out("0.0625", 0, 16, IO_MODE_SCIENTIFIC, "+0x1(-0d1)");
6106   tc_out("0.03125", 0, 16, IO_MODE_SCIENTIFIC, "+0x8(-0d2)");
6107   tc_out("0.75", 0, 16, IO_MODE_SCIENTIFIC, "+0xC(-0d1)");
6108   tc_out("0.96875", 0, 16, IO_MODE_SCIENTIFIC, "+0x1(+0d0)");
6109   tc_out("5.42101086242752217003726400434970855712890625e-20", 0, 16, IO_MODE_SCIENTIFIC, "+0x1(-0d16)");
6110   tc_out("5.42101086242752217003726400434970855712890625e-20", 16, 16, IO_MODE_SCIENTIFIC,
6111               "+0x1.0000000000000000(-0d16)");
6112   tc_out("5.42101086242752217003726400434970855712890625e-20", 15, 16, IO_MODE_SCIENTIFIC,
6113               "+0x1.000000000000000(-0d16)");
6114   tc_out("5.42101086242752217003726400434970855712890625e-20", 14, 16, IO_MODE_SCIENTIFIC,
6115               "+0x1.00000000000000(-0d16)");
6116   tc_out("5.42101086242752217003726400434970855712890625e-20", 13, 16, IO_MODE_SCIENTIFIC,
6117               "+0x1.0000000000000(-0d16)");
6118   tc_out("5.42101086242752217003726400434970855712890625e-20", 12, 16, IO_MODE_SCIENTIFIC,
6119               "+0x1.000000000000(-0d16)");
6120   tc_out("5.42101086242752217003726400434970855712890625e-20", 11, 16, IO_MODE_SCIENTIFIC,
6121               "+0x1.00000000000(-0d16)");
6122   tc_out("5.42101086242752217003726400434970855712890625e-20", 10, 16, IO_MODE_SCIENTIFIC,
6123               "+0x1.0000000000(-0d16)");
6124   tc_out("5.42101086242752217003726400434970855712890625e-20", 9, 16, IO_MODE_SCIENTIFIC,
6125               "+0x1.000000000(-0d16)");
6126   tc_out("5.42101086242752217003726400434970855712890625e-20", 8, 16, IO_MODE_SCIENTIFIC,
6127               "+0x1.00000000(-0d16)");
6128   tc_out("5.42101086242752217003726400434970855712890625e-20", 7, 16, IO_MODE_SCIENTIFIC,
6129               "+0x1.0000000(-0d16)");
6130   tc_out("5.42101086242752217003726400434970855712890625e-20", 6, 16, IO_MODE_SCIENTIFIC,
6131               "+0x1.000000(-0d16)");
6132   tc_out("5.42101086242752217003726400434970855712890625e-20", 5, 16, IO_MODE_SCIENTIFIC,
6133               "+0x1.00000(-0d16)");
6134   tc_out("5.42101086242752217003726400434970855712890625e-20", 4, 16, IO_MODE_SCIENTIFIC,
6135               "+0x1.0000(-0d16)");
6136   tc_out("5.42101086242752217003726400434970855712890625e-20", 3, 16, IO_MODE_SCIENTIFIC,
6137               "+0x1.000(-0d16)");
6138   tc_out("5.42101086242752217003726400434970855712890625e-20", 2, 16, IO_MODE_SCIENTIFIC,
6139               "+0x1.00(-0d16)");
6140   tc_out("5.42101086242752217003726400434970855712890625e-20", 1, 16, IO_MODE_SCIENTIFIC,
6141               "+0x1.0(-0d16)");
6142   tc_out("1", 0, 2, IO_MODE_SCIENTIFIC, "+0b1(+0d0)");
6143   tc_out("2", 0, 2, IO_MODE_SCIENTIFIC, "+0b1(+0d1)");
6144   tc_out("3", 0, 2, IO_MODE_SCIENTIFIC, "+0b1(+0d2)");
6145   tc_out("3", 1, 2, IO_MODE_SCIENTIFIC, "+0b1.1(+0d1)");
6146   tc_out("3", 2, 2, IO_MODE_SCIENTIFIC, "+0b1.10(+0d1)");
6147   tc_out("0.5", 0, 2, IO_MODE_SCIENTIFIC, "+0b1(-0d1)");
6148   tc_out("0.25", 0, 2, IO_MODE_SCIENTIFIC, "+0b1(-0d2)");
6149   tc_out("0.75", 0, 2, IO_MODE_SCIENTIFIC, "+0b1(-0d1)");
6150   tc_out("-0.75", 1, 2, IO_MODE_SCIENTIFIC, "-0b1.1(-0d1)");
6151   tc_out("1", 0, 8, IO_MODE_SCIENTIFIC, "+0o1(+0d0)");
6152   tc_out("2", 0, 8, IO_MODE_SCIENTIFIC, "+0o2(+0d0)");
6153   tc_out("4", 0, 8, IO_MODE_SCIENTIFIC, "+0o4(+0d0)");
6154   tc_out("8", 0, 8, IO_MODE_SCIENTIFIC, "+0o1(+0d1)");
6155   tc_out("16", 0, 8, IO_MODE_SCIENTIFIC, "+0o2(+0d1)");
6156   tc_out("0.5", 0, 8, IO_MODE_SCIENTIFIC, "+0o4(-0d1)");
6157   tc_out("0.75", 0, 8, IO_MODE_SCIENTIFIC, "+0o6(-0d1)");
6158   tc_out("0.875", 0, 8, IO_MODE_SCIENTIFIC, "+0o7(-0d1)");
6159   tc_out("0.9375", 1, 8, IO_MODE_SCIENTIFIC, "+0o7.4(-0d1)");
6160   tc_out("0.9375", 0, 8, IO_MODE_SCIENTIFIC, "+0o1(+0d0)");
6161   tc_out("NaN", 1, 10, IO_MODE_FIXPOINT, "NaN");
6162   tc_out("0", 1, IO_BASE_NAN, IO_MODE_FIXPOINT, "");
6163   tc_out("0", 1, IO_BASE_ZERO, IO_MODE_FIXPOINT, "");
6164   tc_out("1", 1, IO_BASE_NAN, IO_MODE_FIXPOINT, "");
6165   tc_out("0", 1, 5, IO_MODE_FIXPOINT, "");
6166   tc_out("0", 1, 10, IO_MODE_FIXPOINT, "0");
6167   tc_out("1", 0, 10, IO_MODE_FIXPOINT, "+0d1(+0d0)");
6168   tc_out("1", 1, 10, IO_MODE_FIXPOINT, "+0d1.0(+0d0)");
6169   tc_out("10", 0, 10, IO_MODE_FIXPOINT, "+0d10(+0d0)");
6170   tc_out("-10", 0, 10, IO_MODE_FIXPOINT, "-0d10(+0d0)");
6171   tc_out("10", 3, 10, IO_MODE_FIXPOINT, "+0d10.000(+0d0)");
6172   tc_out("10.1", 0, 10, IO_MODE_FIXPOINT, "+0d10(+0d0)");
6173   tc_out("10.1", 1, 10, IO_MODE_FIXPOINT, "+0d10.1(+0d0)");
6174   tc_out("10.1", 2, 10, IO_MODE_FIXPOINT, "+0d10.10(+0d0)");
6175   tc_out("10.12", 1, 10, IO_MODE_FIXPOINT, "+0d10.1(+0d0)");
6176   tc_out("10.16", 1, 10, IO_MODE_FIXPOINT, "+0d10.2(+0d0)");
6177   tc_out("10.86", 0, 10, IO_MODE_FIXPOINT, "+0d11(+0d0)");
6178   tc_out("0.1", 1, 10, IO_MODE_FIXPOINT, "+0d.1(+0d0)");
6179   tc_out("0.12", 1, 10, IO_MODE_FIXPOINT, "+0d.1(+0d0)");
6180   tc_out("0.0123", 2, 10, IO_MODE_FIXPOINT, "+0d.01(+0d0)");
6181   tc_out("18446744073709551616", 0, 10, IO_MODE_FIXPOINT, "+0d18446744073709551616(+0d0)");
6182   tc_out("0.75", 1, 16, IO_MODE_FIXPOINT, "+0x.C(+0d0)");
6183   tc_out("18446744073709551616", 0, 16, IO_MODE_FIXPOINT, "+0x10000000000000000(+0d0)");
6184   tc_out("18446744073709551615", 0, 16, IO_MODE_FIXPOINT, "+0xFFFFFFFFFFFFFFFF(+0d0)");
6185   tc_out("18446744073709551615", 1, 16, IO_MODE_FIXPOINT, "+0xFFFFFFFFFFFFFFFF.0(+0d0)");
6186   tc_out("5.42101086242752217003726400434970855712890625e-20", 16, 16, IO_MODE_FIXPOINT,
6187               "+0x.0000000000000001(+0d0)");
6188   tc_out("-0.75", 2, 2, IO_MODE_FIXPOINT, "-0b.11(+0d0)");
6189   tc_out("0.9375", 2, 8, IO_MODE_FIXPOINT, "+0o.74(+0d0)");
6190   tc_out("4.9375", 2, 8, IO_MODE_FIXPOINT, "+0o4.74(+0d0)");
6191   tc_out("4.9375", 1, 8, IO_MODE_FIXPOINT, "+0o5.0(+0d0)");
6192   tc_out("4.9375", 0, 10, IO_MODE_FIXPOINT, "+0d5(+0d0)");
6193   tc_out("4.9375", 0, 16, IO_MODE_FIXPOINT, "+0x5(+0d0)");
6194   tc_out("4.9375", 0, 8, IO_MODE_FIXPOINT, "+0o5(+0d0)");
6195   tc_out("4.9375", 0, 2, IO_MODE_FIXPOINT, "+0b101(+0d0)");
6196   tc_out("1.23", 2, 10, IO_MODE_ENG, "+0d1.23(+0d0)");
6197   tc_out("12.3", 2, 10, IO_MODE_ENG, "+0d12.3(+0d0)");
6198   tc_out("123", 2, 10, IO_MODE_ENG, "+0d123(+0d0)");
6199   tc_out("1234", 2, 10, IO_MODE_ENG, "+0d1.23(+0d3)");
6200   tc_out("0.1234", 2, 10, IO_MODE_ENG, "+0d123(-0d3)");
6201   tc_out("0.0123", 2, 10, IO_MODE_ENG, "+0d12.3(-0d3)");
6202   tc_out("0.00123", 2, 10, IO_MODE_ENG, "+0d1.23(-0d3)");
6203   tc_out("0.000123", 2, 10, IO_MODE_ENG, "+0d123(-0d6)");
6204   tc_out("-0.000123", 2, 10, IO_MODE_ENG, "-0d123(-0d6)");
6205   tc_out("0", 0, 16, IO_MODE_COMPLEMENT, "0");
6206   tc_out("1", 0, 16, IO_MODE_COMPLEMENT, "0x1(+0d0)");
6207   tc_out("-1", 0, 16, IO_MODE_COMPLEMENT, "0xsF(+0d0)");
6208   tc_out("-2", 0, 16, IO_MODE_COMPLEMENT, "0xsFE(+0d0)");
6209   tc_out("-16", 0, 16, IO_MODE_COMPLEMENT, "0xsF0(+0d0)");
6210   tc_out("-17", 0, 16, IO_MODE_COMPLEMENT, "0xsFEF(+0d0)");
6211 
6212   // Restore default ioparams
6213   for (i = 0 ; i < sizeof(iop) / sizeof(t_ioparams) ; ++i) {
6214     setioparams(&saveiop[i]);
6215   }
6216 
6217   return 1;
6218 }
6219 
_tc_in(const char * file,int line,char * msg,const char * text,char * result)6220 static void _tc_in(const char* file, int line, char* msg, const char* text, char* result)
6221 {
6222   t_itokens tokens;
6223   floatstruct x;
6224   floatstruct r;
6225 
6226   float_create(&x);
6227   float_create(&r);
6228   float_setasciiz(&r, result);
6229   parse(&tokens, &text);
6230   float_in(&x, &tokens);
6231   DisplayErrorOnFloatMismatch(file, line, msg, &x, &r, &g_failed_tests, &g_new_failed_tests, 0);
6232   float_free(&x);
6233   float_free(&r);
6234 }
6235 
test_in()6236 static int test_in()
6237 {
6238   printf("testing float_in\n");
6239 
6240   tc_in("", "NaN");
6241   tc_in("NaN", "NaN");
6242   tc_in("0", "0");
6243   tc_in("0.", "0");
6244   tc_in(".0", "0");
6245   tc_in("+0", "0");
6246   tc_in("0d0", "0");
6247   tc_in("+0d0", "0");
6248   tc_in("-0", "0");
6249   tc_in("0000", "0");
6250   tc_in(".0000", "0");
6251   tc_in("00.00", "0");
6252   tc_in("1", "1");
6253   tc_in("0d1", "1");
6254   tc_in("1.", "1");
6255   tc_in("1.00", "1");
6256   tc_in("001.00", "1");
6257   tc_in("+1", "1");
6258   tc_in("-1", "-1");
6259   tc_in("10", "10");
6260   tc_in("010", "10");
6261   tc_in("010.00", "10");
6262   tc_in("123456789", "123456789");
6263   tc_in("0.1", "0.1");
6264   tc_in(".1", "0.1");
6265   tc_in(".1000", "0.1");
6266   tc_in("000.1000", "0.1");
6267   tc_in(".01000", "0.01");
6268   tc_in(".0123456789000", "0.0123456789");
6269   tc_in("2.1", "2.1");
6270   tc_in("001234.567800", "1234.5678");
6271   tc_in("0012340.567800", "12340.5678");
6272   tc_in("001234.0567800", "1234.05678");
6273   tc_in("0012340.0567800", "12340.05678");
6274   tc_in("1e0", "1");
6275   tc_in("1(0)", "1");
6276   tc_in("1e+0", "1");
6277   tc_in("1e-0", "1");
6278   tc_in("0d1e-0d0", "1");
6279   tc_in("1e1", "10");
6280   tc_in("1e+1", "10");
6281   tc_in("1e-1", "0.1");
6282   tc_in("1.e-1", "0.1");
6283   tc_in("1.2e-1", "0.12");
6284   tc_in("0.2e-1", "0.02");
6285   tc_in("12e-1", "1.2");
6286   tc_in("12e-2", "0.12");
6287   tc_in("12e1", "120");
6288   tc_in("0.12e1", "1.2");
6289   tc_in("0.12e2", "12");
6290   tc_in("0x0", "0");
6291   tc_in("0x1", "1");
6292   tc_in("0x1.0", "1");
6293   tc_in("0x0001", "1");
6294   tc_in("0x0001.00", "1");
6295   tc_in("-0x1", "-1");
6296   tc_in("+0x1", "1");
6297   tc_in("0xA", "10");
6298   tc_in("0xa", "10");
6299   tc_in("0x10", "16");
6300   tc_in("0x10000000000000000", "18446744073709551616");
6301   tc_in("0xFFFFFFFFFFFFFFFF", "18446744073709551615");
6302   tc_in("0x.8", "0.5");
6303   tc_in("0x.4", "0.25");
6304   tc_in("0x.08", "0.03125");
6305   tc_in("0x1.2", "1.125");
6306   tc_in("0x10.C", "16.75");
6307   tc_in("0x1(1)", "16");
6308   tc_in("0x1(-1)", "0.0625");
6309   tc_in("0x1(A)", "1099511627776");
6310   tc_in("0x1(0d10)", "1099511627776");
6311   tc_in("0x1(10)", "18446744073709551616");
6312   tc_in("0x1.1(1)", "17");
6313   tc_in("0x1h1", "16");
6314   tc_in("0x1H-1", "0.0625");
6315   tc_in("0x1hA", "1099511627776");
6316   tc_in("0x1H0d10", "1099511627776");
6317   tc_in("0x1h10", "18446744073709551616");
6318   tc_in("0x1.1H1", "17");
6319   tc_in("0b0", "0");
6320   tc_in("0b1", "1");
6321   tc_in("0b1.0", "1");
6322   tc_in("-0b1", "-1");
6323   tc_in("0b10", "2");
6324   tc_in("0b11", "3");
6325   tc_in("0b.11", ".75");
6326   tc_in("0b1.1", "1.5");
6327   tc_in("0b1.1(-1)", "0.75");
6328   tc_in("0b1.1(1)", "3");
6329   tc_in("0b1.1(0b1)", "3");
6330   tc_in("0b1.1(10)", "6");
6331   tc_in("0b1.1b-1", "0.75");
6332   tc_in("0b1.1B1", "3");
6333   tc_in("0b1.1b0b1", "3");
6334   tc_in("0b1.1B10", "6");
6335   tc_in("0o0", "0");
6336   tc_in("0o1", "1");
6337   tc_in("0o1.0", "1");
6338   tc_in("-0o1", "-1");
6339   tc_in("0o10", "8");
6340   tc_in("0o14", "12");
6341   tc_in("0o.6", ".75");
6342   tc_in("0o1.1", "1.125");
6343   tc_in("0o1.4(-1)", "0.1875");
6344   tc_in("0o1.4(1)", "12");
6345   tc_in("0o1.4(0o1)", "12");
6346   tc_in("0o2(10)", "33554432");
6347   tc_in("0o1.4o-1", "0.1875");
6348   tc_in("0o1.4O1", "12");
6349   tc_in("0o1.4C0o1", "12");
6350   tc_in("0o2o10", "33554432");
6351   tc_in("0xsF", "-1");
6352   tc_in("0xsFF", "-1");
6353   tc_in("0xsFE", "-2");
6354   tc_in("0xsFFE", "-2");
6355   tc_in("0xsF0", "-16");
6356   tc_in("0xsF01", "-255");
6357   tc_in("0bs1", "-1");
6358   tc_in("0bs11", "-1");
6359   tc_in("0bs10", "-2");
6360   tc_in("0bs110", "-2");
6361   tc_in("0bs101", "-3");
6362   tc_in("0os7", "-1");
6363   tc_in("0os77", "-1");
6364   tc_in("0os76", "-2");
6365   tc_in("0os70", "-8");
6366   tc_in("0os767", "-9");
6367   tc_in("0os701", "-63");
6368   return 1;
6369 }
6370 
test_erfnear0()6371 static int test_erfnear0()
6372 {
6373     floatstruct x, x1, tmp, max;
6374     int i;
6375     char buf[50];
6376 
6377     float_create(&x);
6378     float_create(&x1);
6379     float_create(&tmp);
6380     float_create(&max);
6381     float_setzero(&max);
6382 
6383     printf("%s\n", "testing erfnear0");
6384 
6385     printf("verifying special argument x == 0:\n");
6386     float_setzero(&x);
6387     erfnear0(&x, 100);
6388     if (!float_iszero(&x))
6389     {
6390       printf("FAILED\n");
6391       return 0;
6392     }
6393 
6394     /* testing the validity of the series evaluation */
6395     printf("verifying result:\n");
6396     float_setasciiz(&x, "2.7");
6397     float_ln(&x, 100);
6398     erfnear0(&x, 100);
6399     float_setasciiz(&x1,".7443248085801137476495167988933711046591685164758118184461636179213"
6400                         "12059356598790281111307476902061005913670963660509168");
6401     if (!_cmprelerror(&x1, &x, -99))
6402     {
6403       printf("FAILED for x == ln 2.7\n");
6404       return 0;
6405     }
6406 
6407     printf("testing error limit:\n");
6408     /* overall scan for maximum relative error */
6409     float_setscientific(&tmp, ".005", NULLTERMINATED);
6410     for (i = -1; ++i <= 100;)
6411     {
6412       float_muli(&x, &tmp, i, EXACT);
6413       _sub_ulp(&x, 101);
6414       float_copy(&x1, &x, EXACT);
6415       erfnear0(&x,100);
6416       erfnear0(&x1, 110);
6417       _relerror(&x1, &x);
6418       if (float_cmp(&x1, &max) > 0)
6419       {
6420         float_copy(&max, &x1, EXACT);
6421         if (float_getexponent(&x1) >= -99)
6422         {
6423           printf("exceeding error for test case %d: ", i);
6424           float_getscientific(buf, 50, &max);
6425           printf("%s\n", buf);
6426           return 0;
6427         }
6428       }
6429     }
6430     float_getscientific(buf, 50, &max);
6431     printf("max error erfnear0: %s\n", buf);
6432     float_free(&tmp);
6433     float_free(&x);
6434     float_free(&x1);
6435     float_free(&max);
6436     return 1;
6437 }
6438 
test_erfcasymptotic()6439 static int test_erfcasymptotic()
6440 {
6441   floatstruct x, x1, tmp, max;
6442   int i;
6443   char buf[50];
6444 
6445   float_create(&x);
6446   float_create(&x1);
6447   float_create(&tmp);
6448   float_create(&max);
6449   printf("%s\n", "testing erfcasymptotic");
6450 
6451   /* testing the validity of the series evaluation */
6452   printf("verifying result:\n");
6453   float_setasciiz(&x, "16");
6454   erfcasymptotic(&x, 100);
6455   float_setasciiz(&x1,".99805820883474330725563527001359438444222962655197"
6456                       "570407974747783849037252552071214598018034509890346"
6457                       "673633987464964958201780044076702727433644232998947"
6458                       "151419098605560850226039542578816264384967072263818");
6459   if (!_cmprelerror(&x1, &x, -99))
6460   {
6461     printf("FAILED for x == 16\n");
6462     return 0;
6463   }
6464 
6465   printf("testing error limit:\n");
6466   /* overall scan for maximum relative error */
6467   float_setzero(&max);
6468   float_setscientific(&tmp, ".005", NULLTERMINATED);
6469   for (i = -1; ++i <= 100;)
6470   {
6471     float_muli(&x, &tmp, i, EXACT);
6472     float_addi(&x, &x, 16, EXACT);
6473     _sub_ulp(&x, 101);
6474     float_copy(&x1, &x, EXACT);
6475     erfcasymptotic(&x,100);
6476     erfcasymptotic(&x1, 110);
6477     _relerror(&x1, &x);
6478     if (float_cmp(&x1, &max) > 0)
6479     {
6480       float_copy(&max, &x1, EXACT);
6481       if (float_getexponent(&x1) >= -99)
6482       {
6483         printf("exceeding error for test case %d: ", i);
6484         float_getscientific(buf, 50, &max);
6485         printf("%s\n", buf);
6486         return 0;
6487       }
6488     }
6489   }
6490   float_getscientific(buf, 50, &max);
6491   printf("max error erfcasymptotic: %s\n", buf);
6492 
6493   printf("testing convergence:\n");
6494   float_copy(&x, &c2, EXACT);
6495   if (!erfcasymptotic(&x, 1))
6496   {
6497     printf("convergence failed for 1 digit");
6498     return 0;
6499   }
6500   float_setasciiz(&max, "0.92");
6501   float_copy(&tmp, &max, EXACT);
6502   float_ln(&max, 100);
6503   float_sub(&max, &c1, &max, 100);
6504   float_mul(&max, &tmp, &max, 100);
6505   float_mul(&x1, &c1Div2, &cLn2, 100);
6506   for (i = 1; ++i <= 100;)
6507   {
6508     float_muli(&x, &cLn10, i, 100);
6509     float_add(&x, &x, &x1, 100);
6510     float_div(&x, &x, &max, 100);
6511     float_sqrt(&x, 100);
6512     if (!erfcasymptotic(&x, i))
6513     {
6514       printf("convergence failed for %d digits", i);
6515       return 0;
6516     }
6517   }
6518   printf("convergence ok\n");
6519 
6520   float_free(&max);
6521   float_free(&tmp);
6522   float_free(&x);
6523   float_free(&x1);
6524   return 1;
6525 }
6526 
test_erfcsum()6527 static int test_erfcsum()
6528 {
6529   floatstruct x, x1, tmp, max;
6530   int i, prec;
6531   char  buf[50];
6532 
6533   printf("testing erfcsum IGNORED\n");
6534   return 1;
6535 
6536   float_create(&x);
6537   float_create(&x1);
6538   float_create(&tmp);
6539   float_create(&max);
6540   printf("testing erfcsum\n");
6541 
6542   printf("testing error limit:\n");
6543   /* overall scan for maximum relative error */
6544   float_setscientific(&tmp, ".4", NULLTERMINATED);
6545   for (prec = 1; ++prec <= 100;)
6546   {
6547     float_muli(&tmp, &cLn10, prec, 4);
6548     float_setasciiz(&x, "0.3466");
6549     float_add(&tmp, &tmp, &x, 4);
6550     float_setasciiz(&x, "0.9967");
6551     float_div(&tmp, &tmp, &x, 4);
6552     float_sqrt(&tmp, 4);
6553     float_sub(&tmp, &tmp, &c1Div2, 4);
6554     float_divi(&tmp, &tmp, 20, 4);
6555     float_setzero(&max);
6556     for (i = -1; ++i <= 20;)
6557     {
6558       float_muli(&x, &tmp, i, EXACT);
6559       float_add(&x, &x, &c1Div2, EXACT);
6560       _sub_ulp(&x, 101);
6561       float_copy(&x1, &x, EXACT);
6562       if (!erfcsum(&x1, prec+1) || !erfcsum(&x, prec))
6563       {
6564         printf("no convergence test case %d, prec %d: ", i, prec);
6565         return 0;
6566       }
6567       _relerror(&x1, &x);
6568       if (float_cmp(&x1, &max) > 0)
6569       {
6570         float_copy(&max, &x1, EXACT);
6571         if (float_getexponent(&x1) >= -prec+1)
6572         {
6573           printf("exceeding error for test case %d, prec %d: ", i, prec);
6574           float_getscientific(buf, 50, &max);
6575           printf("%s\n", buf);
6576           return 0;
6577         }
6578       }
6579     }
6580   }
6581   float_getscientific(buf, 50, &max);
6582   printf("max error erfcsum: %s\n", buf);
6583 
6584   /* testing the validity of the series evaluation */
6585   printf("verifying result:\n");
6586   float_setasciiz(&tmp, "20");
6587   float_divi(&tmp, &tmp, 7, 110);
6588   float_mul(&x, &tmp, &tmp, 110);
6589   erfcsum(&x, 100);
6590   /* we cannot know the free parameter alpha earlier, as it might be changed
6591   during the last series evaluation */
6592   float_mul(&x1, &tmp, &c2Pi, 110);
6593   float_div(&x1, &x1, &erfcalpha, 110);
6594   _exp(&x1, 110);
6595   float_sub(&x1, &c1, &x1, 110);
6596   float_div(&x1, &c2, &x1, 110);
6597   /* erfc (20/7) */
6598   float_setasciiz(&max,"0.00005331231138832281466765963565935"
6599                        "9917631684842756273950127577016997393"
6600                        "623370565496031160355771016945224924345871");
6601   float_sub(&x1, &max, &x1, 110);
6602   float_div(&x1, &x1, &tmp, 110);
6603   float_div(&x1, &x1, &erfcalpha, 110);
6604   float_mul(&x1, &x1, &cPi, 110);
6605   float_mul(&max, &tmp, &tmp, 110);
6606   float_copy(&tmp, &max, EXACT);
6607   _exp(&tmp, 110);
6608   float_reciprocal(&max, 110);
6609   float_mul(&x1, &x1, &tmp, 110);
6610   float_sub(&x1, &x1, &max, 110);
6611   float_mul(&x1, &x1, &c1Div2, 110);
6612 
6613   if (!_cmprelerror(&x1, &x, -99))
6614   {
6615     printf("FAILED for x == 20/7\n");
6616     return 0;
6617   }
6618 
6619   float_free(&x);
6620   float_free(&x1);
6621   float_free(&tmp);
6622   float_free(&max);
6623   return 1;
6624 }
6625 
test_erfc()6626 static int test_erfc()
6627 {
6628   int prec, i;
6629   floatstruct x, x1, step1;
6630   floatstruct results[40];
6631 
6632   printf("testing erfc IGNORED\n");
6633   return 1;
6634 
6635   printf("testing erfc\n");
6636   float_create(&x);
6637   float_create(&x1);
6638   float_create(&step1);
6639   for (i = -1; ++i < 40;)
6640     float_create(&results[i]);
6641   printf("testing special values\n");
6642   float_setzero(&x);
6643   float_erfc(&x, 100);
6644   if (float_cmp(&x, &c1) != 0)
6645     return 0;
6646   float_setasciiz(&x, "-1e1000000");
6647   float_erfc(&x, 100);
6648   if (float_cmp(&x, &c2) != 0)
6649     return 0;
6650   printf("verifying results\n");
6651   float_setinteger(&x, 7);
6652   float_reciprocal(&x, 110);
6653   float_erfc(&x, 100);
6654   float_setasciiz(&step1, "0.83989287327126887336609000468499807511227817903"
6655                        "914160714981066604747285032020973498955714529213539694928510963");
6656   if (!_cmprelerror(&step1, &x, -99))
6657   {
6658     printf("FAILED for x == 1/7\n");
6659     return 0;
6660   }
6661   float_setinteger(&x, 20);
6662   float_divi(&x, &x, 7, 110);
6663   float_erfc(&x, 100);
6664   float_setasciiz(&step1, "0.00005331231138832281466765963565935991763168484275"
6665                           "6273950127577016997393623370565496031160355771016945224924345871");
6666   if (!_cmprelerror(&step1, &x, -99))
6667   {
6668     printf("FAILED for x == 20/7\n");
6669     return 0;
6670   }
6671   float_setinteger(&x, 93);
6672   float_divi(&x, &x, 7, 110);
6673   float_erfc(&x, 100);
6674   float_setasciiz(&step1, "9.31989223711981967164397263120561981131962901479240254614838756"
6675                           "73754394641320672442272563375006637085970867544e-79");
6676   if (!_cmprelerror(&step1, &x, -98))
6677   {
6678     printf("FAILED for x == 93/7\n");
6679     return 0;
6680   }
6681   float_setasciiz(&x, "283.6");
6682   float_erfc(&x, 100);
6683   float_setasciiz(&step1, "2.787423261346745115871691439975638770369249289940553698308352"
6684                           "9939376478760274499258439317477920123004576049401e-34933");
6685   if (!_cmprelerror(&step1, &x, -95))
6686   {
6687     printf("FAILED for x == 283.6\n");
6688     return 0;
6689   }
6690   float_setasciiz(&step1, "0.1");
6691   printf("precision test for erfc\n");
6692   for (prec = 0; ++prec <= 100;)
6693   {
6694     printf("%d\n", prec);
6695     /* clear all cached coefficients */
6696     erfcdigits = 0;
6697     for (i = 0; ++i < 100;)
6698     {
6699       float_setinteger(&x, 1);
6700       float_setexponent(&x, -i);
6701       _sub_ulp(&x, prec);
6702       float_copy(&x1, &x, EXACT);
6703       float_erfc(&x, prec);
6704       float_erfc(&x1, prec+4);
6705       if (!_cmprelerror(&x, &x1, -prec))
6706       {
6707         printf("evaluation IMPRECICE for 1e-%d\n", i);
6708         return 0;
6709       }
6710     }
6711     for (i = 0; ++i <= 39;)
6712     {
6713       if (i < 10)
6714         float_muli(&x, &step1, i, EXACT);
6715       else if (i < 30)
6716         float_setinteger(&x, i-9);
6717       else
6718         float_setinteger(&x, (i-25)*(i-25));
6719       _sub_ulp(&x, prec);
6720       if(!float_erfc(&x, prec))
6721       {
6722         printf("evaluation FAILED for case %d\n", i);
6723         return 0;
6724       }
6725       float_move(&results[i], &x);
6726     }
6727     for (i = 0; ++i <= 39;)
6728     {
6729       if (i < 10)
6730         float_muli(&x, &step1, i, EXACT);
6731       else if (i < 30)
6732         float_setinteger(&x, i-9);
6733       else
6734         float_setinteger(&x, (i-25)*(i-25));
6735       _sub_ulp(&x, prec);
6736       if(!float_erfc(&x, prec+4))
6737       {
6738         printf("evaluation FAILED for case %d\n", i);
6739         return 0;
6740       }
6741       if (!_cmprelerror(&x, &results[i], -prec))
6742       {
6743         printf("evaluation IMPRECICE for case %d\n", i);
6744         return 0;
6745       }
6746     }
6747   }
6748   float_free(&x);
6749   float_free(&step1);
6750   float_free(&x1);
6751   for (i = -1; ++i < 40;)
6752     float_free(&results[i]);
6753   return 1;
6754 }
6755 
test_erf()6756 static int test_erf()
6757 {
6758   int prec, i;
6759   floatstruct x, x1, step;
6760 
6761   printf("testing erf\n");
6762   float_create(&x);
6763   float_create(&step);
6764   float_create(&x1);
6765   printf("verifying special x");
6766   float_setzero(&x);
6767   if (!float_erf(&x,100) || !float_iszero(&x))
6768     return 0;
6769   float_setasciiz(&x, "1e1000000");
6770   if (!float_erf(&x, 100) || float_cmp(&x, &c1) != 0)
6771     return 0;
6772   float_copy(&x1, &c1, EXACT);
6773   float_copy(&x, &cMinus1, EXACT);
6774   if (!float_erf(&x, 100) || !float_erf(&x1, 100))
6775     return 0;
6776   float_neg(&x);
6777   if (float_cmp(&x, &x1) != 0)
6778     return 0;
6779   float_setasciiz(&step, "0.05");
6780   printf("precision test for erf\n");
6781   for (prec = 0; ++prec <= 100;)
6782   {
6783     printf("%d\n", prec);
6784     for (i = 0; ++i <= 39;)
6785     {
6786       if (i < 10)
6787       {
6788         float_copy(&x, &c1, EXACT);
6789         float_setexponent(&x, -3-i*i);
6790       }
6791       else if (i < 30)
6792         float_muli(&x, &step, i-9, EXACT);
6793       else
6794         float_setinteger(&x, 2 + (i-30)*(i-30));
6795       _sub_ulp(&x, prec);
6796       float_copy(&x1, &x, EXACT);
6797       if(!float_erf(&x, prec) || !float_erf(&x1, prec+4))
6798       {
6799         printf("evaluation FAILED for case %d\n", i);
6800         return 0;
6801       }
6802       if (!_cmprelerror(&x, &x1, -prec))
6803       {
6804         printf("evaluation IMPRECICE for case %d\n", i);
6805         return 0;
6806       }
6807     }
6808   }
6809   float_free(&x);
6810   float_free(&step);
6811   float_free(&x1);
6812   return 1;
6813 }
6814 
testfailed(char * msg)6815 static int testfailed(char* msg)
6816 {
6817   printf("\n%s FAILED, tests aborted\n", msg);
6818   return 1;
6819 }
6820 
6821 #endif /* _FLOATNUMTEST */
6822 
main(int argc,char * argv[])6823 int main(int argc, char* argv[])
6824 {
6825 
6826 #ifdef _FLOATNUMTEST
6827   int scalesave;
6828 
6829   printf("\ntest of floatlong\n");
6830   floatmath_init();
6831   float_stdconvert();
6832   maxdigits = 150;
6833 
6834   if(!test_longadd()) return testfailed("_longadd");
6835   if(!test_longmul()) return testfailed("_longmul");
6836   if(!test_longshr()) return testfailed("_longshr");
6837   if(!test_checkadd()) return testfailed("_checkadd");
6838   if(!test_checkmul()) return testfailed("_checkmul");
6839   if(!test_longarrayadd()) return testfailed("_longarrayadd");
6840   if(!test_longarraymul()) return testfailed("_longarrayadd");
6841 
6842   printf("\ntest of setting/modifying values \n");
6843 
6844   scalesave = maxdigits;
6845   maxdigits = 15;
6846 
6847   if(!test_create()) return testfailed("float_create");
6848   if(!test_isnan()) return testfailed("float_isnan");
6849   if(!test_iszero()) return testfailed("float_iszero");
6850   if(!test_setnan()) return testfailed("float_setnan");
6851   if(!test_setzero()) return testfailed("float_setzero");
6852   if(!test_setsignificand()) return testfailed("float_setsignificand");
6853   if(!test_getsignificand()) return testfailed("float_getsignificand");
6854   if(!test_setexponent()) return testfailed("float_setexponent");
6855   if(!test_getexponent()) return testfailed("float_getexponent");
6856   if(!test_setsign()) return testfailed("float_setsign");
6857   if(!test_getsign()) return testfailed("float_getsign");
6858   if(!test_getlength()) return testfailed("float_getlength");
6859   if(!test_getdigit()) return testfailed("float_getdigit");
6860   if(!test_getscientific()) return testfailed("float_getscientific");
6861   if(!test_setscientific()) return testfailed("float_setscientific");
6862   if(!test_setinteger()) return testfailed("float_setinteger");
6863 
6864   printf("\ntest of basic arithmetic \n");
6865 
6866   if(!test_neg()) return testfailed("float_changesign");
6867   if(!test_abs()) return testfailed("float_abs");
6868   if(!test_cmp()) return testfailed("float_cmp");
6869   if(!test_copy()) return testfailed("float_copy");
6870   if(!test_move()) return testfailed("float_move");
6871   if(!test_round()) return testfailed("float_round");
6872   if(!test_add()) return testfailed("float_add");
6873   if(!test_sub()) return testfailed("float_sub");
6874   if(!test_mul()) return testfailed("float_mul");
6875   if(!test_div()) return testfailed("float_div");
6876   if(!test_sqrt()) return testfailed("float_sqrt");
6877   if(!test_int()) return testfailed("float_int");
6878   if(!test_frac()) return testfailed("float_frac");
6879   if(!test_divmod()) return testfailed("float_divmod");
6880   printf("\nall floatnum tests PASSED\n\n");
6881   maxdigits = scalesave;
6882 
6883   if(!test_floatnum2longint()) return testfailed("_floatnum2longint");
6884   if(!test_longint2floatnum()) return testfailed("_longint2floatnum");
6885   if(!test_out()) return testfailed("float_out");
6886   if(!test_in()) return testfailed("float_in");
6887 
6888   if(!test_floatnum2logic()) return testfailed("_floatnum2logic");
6889   if(!test_logic2floatnum()) return testfailed("_logic2floatnum");
6890   if(!test_not()) return testfailed("float_not");
6891   if(!test_and()) return testfailed("float_and");
6892   if(!test_or()) return testfailed("float_or");
6893   if(!test_xor()) return testfailed("float_xor");
6894   if(!test_shl()) return testfailed("float_shl");
6895   if(!test_shr()) return testfailed("float_shr");
6896   if(!test_raisei()) return testfailed("_raisei");
6897 
6898   if(!test_raiseposi()) return testfailed("_raiseposi");
6899   if(!test_coshminus1near0()) return testfailed("coshminus1near0");
6900   if(!test_artanhnear0()) return testfailed("artanhnear0");
6901   if(!test_cosminus1near0()) return testfailed("cosminus1near0");
6902   if(!test_arctannear0()) return testfailed("arctannear0");
6903   if(!test_lnxplus1near0()) return testfailed("_lnxplus1near0");
6904   if(!test_lnreduce()) return testfailed("_lnreduce");
6905   if(!test_lnxplus1lt1()) return testfailed("_lnxplus1lt1");
6906   if(!test_ln()) return testfailed("_ln");
6907   if(!test_lnxplus1()) return testfailed("_lnxplus1");
6908   if(!test_artanh1minusx()) return testfailed("_artanh1minusx");
6909   if(!test_artanhlt0_5()) return testfailed("_artanhlt0_5");
6910   if(!test_arsinh()) return testfailed("_arsinh");
6911   if(!test_arcoshxplus1()) return testfailed("_arcoshxplus1");
6912   if(!test_coshminus1lt1()) return testfailed("_coshminus1lt1");
6913   if(!test_sinhlt1()) return testfailed("_sinhlt1");
6914   if(!test_expminus1lt1()) return testfailed("_expminus1lt1");
6915   if(!test_expltln10()) return testfailed("_expltln10");
6916   if(!test_exp()) return testfailed("_exp");
6917   if(!test_expminus1()) return testfailed("_expminus1");
6918   if(!test_coshminus1()) return testfailed("_coshminus1");
6919   if(!test_tanhlt0_5()) return testfailed("_tanhlt0_5");
6920   if(!test_tanhminus1gt0()) return testfailed("_tanhminus1gt0");
6921   if(!test_arctanlt1()) return testfailed("_arctanlt1");
6922   if(!test_arctan()) return testfailed("_arctan");
6923   if(!test_arccosxplus1lt0_5()) return testfailed("_arccosxplus1lt0_5");
6924   if(!test_arcsinlt0_5()) return testfailed("_arcsinlt0_5");
6925   if(!test_arccos()) return testfailed("_arccos");
6926   if(!test_arcsin()) return testfailed("_arcsin");
6927   if(!test_cosminus1ltPiDiv4()) return testfailed("_cosminus1ltPiDiv4");
6928   if(!test_sinltPiDiv4()) return testfailed("_sinltPiDiv4");
6929   if(!test_tanltPiDiv4()) return testfailed("_tanltPiDiv4");
6930   if(!test_cos()) return testfailed("_cos");
6931   if(!test_sin()) return testfailed("_sin");
6932   if(!test_tan()) return testfailed("_tan");
6933   if(!test_binetasymptotic()) return testfailed("lngammaseries");
6934   if(!test_pochhammer()) return testfailed("_pochhammer");
6935   if(!test_lngamma()) return testfailed("_lngamma");
6936   if(!test_gamma()) return testfailed("_gamma");
6937   if(!test_gammaint()) return testfailed("_gammaint");
6938   if(!test_gamma0_5()) return testfailed("_gamma0_5");
6939   if(!test_erfnear0()) return testfailed("erfnear0");
6940   if(!test_erfcasymptotic()) return testfailed("erfcasymptotic");
6941   if(!test_erfcsum()) return testfailed("erfcsum");
6942   if(!test_erfc()) return testfailed("erfc");
6943   if(!test_erf()) return testfailed("erf");
6944 
6945   printf("\nall tests PASSED\n");
6946 #endif /* _FLOATNUMTEST */
6947   return 0;
6948 };
6949