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(");
2311
2312 printf("%s", msg);
2313 float_setscientific(", "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(", &v1, &v2, digits);
2319
2320 float_getscientific(buf, 30, ");
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(");
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