1 //==============================================================================================
2 //
3 // This file is part of LiDIA --- a library for computational number theory
4 //
5 // Copyright (c) 1994--2001 the LiDIA Group. All rights reserved.
6 //
7 // See http://www.informatik.tu-darmstadt.de/TI/LiDIA/
8 //
9 //----------------------------------------------------------------------------------------------
10 //
11 // $Id$
12 //
13 // Author : Thomas Papanikolaou (TP)
14 // Changes : See CVS log
15 //
16 //==============================================================================================
17
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22 #include "LiDIA/bigfloat.h"
23 #include "LiDIA/bigfloat_config.h"
24 #include <cstdlib>
25 #include <cstring>
26 #include <cctype>
27
28
29
30 #ifdef LIDIA_NAMESPACE
31 namespace LiDIA {
32 #endif
33
34
35
36 //
37 // assigners
38 //
39
40 void
assign(const bigint & y)41 bigfloat::assign (const bigint & y)
42 {
43 m.assign(y);
44 e = 0;
45 prec = m.bit_length();
46 base_digit_normalize();
47 if (prec == 0)
48 flag() = PlusZero;
49 else
50 flag() = Exact;
51 }
52
53
54
55 void
assign(const bigint & x,const bigint & y)56 bigfloat::assign (const bigint & x, const bigint & y)
57 {
58 bigint q, r;
59
60 div_rem(q, r, x, y);
61 if (r.is_zero()) {
62 m.assign(q);
63 e = 0;
64 prec = m.bit_length();
65 base_digit_normalize();
66 if (prec == 0)
67 flag() = PlusZero;
68 else
69 flag() = Exact;
70 }
71 else {
72 bigfloat tmp(y);
73 assign(x);
74 divide(*this, *this, tmp);
75 }
76 }
77
78
79
80 void
assign(const bigfloat & y)81 bigfloat::assign (const bigfloat & y)
82 {
83 if (&y != this) {
84 m.assign(y.m);
85 e = y.e;
86 prec = y.prec;
87 flag() = y.flag();
88 }
89 }
90
91
92
93 void
assign(double d)94 bigfloat::assign (double d)
95 {
96 base_digit mant;
97 int expo;
98 int s = 0;
99 int ndigits = 0;
100
101 if (d == 0.0) {
102 assign_zero();
103 }
104 else {
105 if (d < 0.0) {
106 s = 1;
107 d = -d;
108 }
109
110 d = std::frexp(d, &expo);
111 m.assign_zero();
112 while (d != 0) {
113 d = std::ldexp(d, bits_per_base_digit);
114 mant = static_cast<base_digit>(d);
115 d -= mant;
116 ndigits++;
117 shift_left(m, m, bits_per_base_digit);
118 add(m, m, bigint(mant));
119 }
120 if (s)
121 m.negate();
122 e = expo - (ndigits * bits_per_base_digit);
123 prec = m.bit_length();
124 base_digit_normalize();
125 flag() = NotExact;
126 }
127 }
128
129
130
131 void
assign(const xdouble & xd)132 bigfloat::assign (const xdouble & xd)
133 {
134 bigfloat temp(xd.l());
135 assign(xd.h());
136 add(*this, *this, temp);
137 // char s[200];
138 // xdouble_to_string(s, xd);
139 // string_to_bigfloat(s, *this);
140 }
141
142
143
144 void
assign(int i)145 bigfloat::assign (int i)
146 {
147 m.assign(i);
148 e = 0;
149 prec = m.bit_length();
150 base_digit_normalize();
151 if (prec == 0)
152 flag() = PlusZero;
153 else
154 flag() = Exact;
155 }
156
157
158
159 void
assign(long i)160 bigfloat::assign (long i)
161 {
162 m.assign(i);
163 e = 0;
164 prec = m.bit_length();
165 base_digit_normalize();
166 if (prec == 0)
167 flag() = PlusZero;
168 else
169 flag() = Exact;
170 }
171
172
173
174 void
assign(unsigned long ui)175 bigfloat::assign (unsigned long ui)
176 {
177 m.assign(ui);
178 e = 0;
179 prec = m.bit_length();
180 base_digit_normalize();
181 if (prec == 0)
182 flag() = PlusZero;
183 else
184 flag() = Exact;
185 }
186
187
188
189 void
assign_exact_zero()190 bigfloat::assign_exact_zero ()
191 {
192 m.assign_zero();
193 e = 0;
194 prec = 0;
195 flag() = PlusZero;
196 }
197
198
199
200 void
assign_zero()201 bigfloat::assign_zero ()
202 {
203 m.assign_zero();
204 e = -bigfloat::binary_precision;
205 prec = 0;
206 flag() = NotExact;
207 }
208
209
210
211 void
assign_one()212 bigfloat::assign_one ()
213 {
214 m.assign_one();
215 e = 0;
216 prec = 1;
217 base_digit_normalize();
218 flag() = Exact;
219 }
220
221
222
223 //
224 // comparators
225 //
226
227 int
abs_compare(const bigfloat & y) const228 bigfloat::abs_compare (const bigfloat & y) const
229 {
230 long sx, sy, ex, ey;
231
232 if (&y == this) {
233 return 0;
234 }
235
236 sx = m.sign();
237 sy = y.m.sign();
238 if (sx == 0) {
239 return ((sy == 0) ? 0 : -1);
240 }
241 if (sy == 0) {
242 return 1;
243 }
244 // sx and sy are non zero
245
246 ex = e + m.bit_length();
247 ey = y.e + y.m.bit_length();
248
249 if (ex > ey) {
250 // |x| > |y|
251 return 1;
252 }
253 if (ex < ey) {
254 // |x| < |y|
255 return -1;
256 }
257
258 // ex = ey, i.e. x and y have the same magnitude
259 bigfloat tmp;
260
261 if (sx == sy) {
262 subtract(tmp, *this, y);
263 }
264 else {
265 add(tmp, *this, y);
266 }
267 return ((sx > 0) ? tmp.sign() : -tmp.sign());
268 }
269
270
271
272 int
compare(const bigfloat & y) const273 bigfloat::compare (const bigfloat & y) const
274 {
275 long sx, sy, ex, ey;
276
277 if (&y == this) {
278 return 0;
279 }
280
281 sx = m.sign();
282 sy = y.m.sign();
283 if (sx > sy) {
284 return 1;
285 }
286 if (sx < sy) {
287 return -1;
288 }
289 // sx = sy, i.e. x and y have the same sign
290
291 if (sx == 0) {
292 // since sx = sy = 0, x = y = 0
293 return 0;
294 }
295
296 ex = e + m.bit_length();
297 ey = y.e + y.m.bit_length();
298 if (ex > ey) {
299 // |x| > |y|
300 return ((sx > 0) ? 1 : -1);
301 }
302 if (ex < ey) {
303 // |x| < |y|
304 return ((sx < 0) ? 1 : -1);
305 }
306
307 // ex = ey, i.e. x and y have the same magnitude
308 bigfloat tmp;
309
310 subtract(tmp, *this, y);
311 return tmp.sign();
312 }
313
314
315
316 //
317 // predicates
318 //
319
320 bool
is_char() const321 bigfloat::is_char () const
322 {
323 if (is_zero())
324 return true;
325
326 bigfloat tmp;
327 truncate(tmp, *this);
328 bool b = (compare(tmp) == 0 && (tmp.precision() <= bits_per_(char)));
329
330 return b;
331 }
332
333
334
335 bool
is_uchar() const336 bigfloat::is_uchar () const
337 {
338 if (is_zero())
339 return true;
340
341 bigfloat tmp;
342 truncate(tmp, *this);
343 bool b = (compare(tmp) == 0 && (tmp.precision() <= bits_per_(unsigned char)));
344
345 return b;
346 }
347
348
349
350 bool
is_short() const351 bigfloat::is_short () const
352 {
353 if (is_zero())
354 return true;
355
356 bigfloat tmp;
357 truncate(tmp, *this);
358 bool b = (compare(tmp) == 0 && (tmp.precision() <= bits_per_(short)));
359
360 return b;
361 }
362
363
364
365 bool
is_ushort() const366 bigfloat::is_ushort () const
367 {
368
369 if (is_zero())
370 return true;
371
372 bigfloat tmp;
373 truncate(tmp, *this);
374 bool b = (compare(tmp) == 0 && (tmp.precision() <= bits_per_(unsigned short)));
375
376 return b;
377 }
378
379
380
381 bool
is_int() const382 bigfloat::is_int () const
383 {
384
385 if (is_zero())
386 return true;
387
388 bigfloat tmp;
389 truncate(tmp, *this);
390 bool b = (compare(tmp) == 0 && (tmp.precision() <= bits_per_(int)));
391
392 return b;
393 }
394
395
396
397 bool
is_uint() const398 bigfloat::is_uint () const
399 {
400
401 if (is_zero())
402 return true;
403
404 bigfloat tmp;
405 truncate(tmp, *this);
406 bool b = (compare(tmp) == 0 && (tmp.precision() <= bits_per_(unsigned int)));
407
408 return b;
409 }
410
411
412
413 bool
is_long() const414 bigfloat::is_long () const
415 {
416
417 if (is_zero())
418 return true;
419
420 bigfloat tmp;
421 truncate(tmp, *this);
422 bool b = (compare(tmp) == 0 && (tmp.precision() <= bits_per_(long)));
423
424 return b;
425 }
426
427
428
429 bool
is_ulong() const430 bigfloat::is_ulong () const
431 {
432
433 if (is_zero())
434 return true;
435
436 bigfloat tmp;
437 truncate(tmp, *this);
438 bool b = (compare(tmp) == 0 && (tmp.precision() <= bits_per_(unsigned long)));
439
440 return b;
441 }
442
443
444
445 bool
is_double() const446 bigfloat::is_double () const
447 {
448 long ex = precision();
449
450 if (ex == 0)
451 return true;
452 ex += exponent();
453 return ((ex <= 0x3ff) && (ex > -1023));
454 }
455
456
457
458 //
459 // converters
460 //
461
462 void
bigintify(bigint & y) const463 bigfloat::bigintify (bigint & y) const
464 {
465 bigfloat r = round(*this);
466 y.assign(r.m);
467 if (r.e > 0)
468 shift_left(y, y, r.e);
469 else
470 shift_right(y, y, -r.e);
471 }
472
473
474
475 bool
doublify(double & d) const476 bigfloat::doublify (double &d) const
477 {
478 long l = m.bit_length(), expo = e + l;
479
480 if (m.is_zero() || (expo < -1023)) {
481 d = 0.0;
482 return false;
483 }
484
485 if (expo >= 0x3ff) {
486 warning_handler("bigfloat", "impossible assignment double = bigfloat");
487 return true;
488 }
489
490 if (l > (SIZEOF_DOUBLE * 8)) {
491 long ed = l - (SIZEOF_DOUBLE * 8);
492 bigint bd = m >> ed; // bd = (m/2^ed)*2^ed
493 d = dbl(bd) * std::ldexp(2.0, static_cast<int>(e + ed - 1));
494 }
495 else
496 d = dbl(m) * std::ldexp(2.0, static_cast<int>(e - 1));
497 return false;
498 }
499
500
501
502 bool
xdoublify(xdouble & xd) const503 bigfloat::xdoublify (xdouble &xd) const
504 {
505 long l = m.bit_length(), expo = e + l;
506
507 if (m.is_zero() || (expo < -996)) {
508 xd = 0.0;
509 return false;
510 }
511
512 if (expo >= 996) {
513 warning_handler("bigfloat", "impossible assignment xdouble = bigfloat"
514 );
515 return true;
516 }
517
518 if (l > (2*SIZEOF_DOUBLE * 8)) {
519 long ed = l - (2*SIZEOF_DOUBLE * 8);
520 bigint bd = m >> ed; // bd = (m/2^ed)*2^ed
521 xd = xdbl(bd) * exp(log(static_cast<xdouble>(2.0)) * static_cast<int>(e + ed));
522 }
523 else
524 xd = xdbl(m) * exp(log(static_cast<xdouble>(2.0)) * static_cast<int>(e));
525 return false;
526 }
527
528
529
530 bool
longify(long & i) const531 bigfloat::longify (long &i) const
532 {
533 double d;
534 int flag;
535 flag = doublify(d);
536 if (flag == 1 || (d > max_long)) {
537 warning_handler("bigfloat", "impossible assignment long = bigfloat");
538 return true;
539 }
540 i = static_cast<long>(d);
541 return false;
542 }
543
544
545
546 bool
intify(int & i) const547 bigfloat::intify (int &i) const
548 {
549 double d;
550 int flag;
551
552 flag = doublify(d);
553 if (flag == 1 || (d > max_int)) {
554 warning_handler("bigfloat", "impossible assignment int = bigfloat");
555 return true;
556 }
557 i = static_cast<int>(d);
558 return false;
559 }
560
561
562
563 //
564 // modifiers
565 //
566
567 void
invert()568 bigfloat::invert ()
569 {
570 bigint one(1UL), mant(m);
571 long t = bigfloat::binary_precision;
572
573 t += ((mant.length() + 1) * bits_per_base_digit);
574 LiDIA::shift_left(one, one, t);
575 div_rem(m, one, one, mant);
576 e = -t - e;
577 prec = m.bit_length();
578 flag() = NotExact;
579 normalize();
580 }
581
582
583
584 void
swap(bigfloat & x)585 bigfloat::swap (bigfloat & x)
586 {
587 long t = x.e;
588 x.e = e;
589 e = t;
590
591 t = x.prec;
592 x.prec = prec;
593 prec = t;
594
595 bigfloat_flag f;
596 f.flag() = x.flag();
597 x.flag() = flag();
598 flag() = f.flag();
599
600 m.swap(x.m);
601 }
602
603
604
605 //
606 // procedural arithmetic
607 //
608
609 void
add(bigfloat & sum,const bigfloat & x,const bigfloat & y)610 add (bigfloat & sum, const bigfloat & x, const bigfloat & y)
611 {
612 const bigfloat *px, *py;
613 long log_x = x.e + x.prec, log_y = y.e + y.prec;
614 long log_dif = log_x - log_y;
615 long ed, e1, e2;
616
617 if (log_dif < 0) {
618 px = &y;
619 py = &x;
620 log_dif = -log_dif;
621 }
622 else {
623 px = &x;
624 py = &y;
625 }
626
627
628 e1 = px->e;
629 e2 = py->e;
630
631 int exp_error = check_overflow(ed, e1, -e2);
632 // ed = |e1 - e2|
633
634 if (exp_error) {
635 if (exp_error > 0)
636 lidia_error_handler("add", "exponent overflow");
637 else
638 lidia_error_handler("add", "exponent undeflow.");
639 }
640
641 if (bigfloat::rounding_mode != MP_EXACT)
642 if (log_dif > (bigfloat::binary_precision + rounding_bits)) {
643 sum.assign(*px);
644 return;
645 }
646
647 if (ed > 0) {
648 bigint tmp(px->m);
649 shift_left(tmp, tmp, ed);
650 add(sum.m, tmp, py->m);
651 sum.e = e2;
652 }
653 else {
654 bigint tmp(py->m);
655 shift_left(tmp, tmp, -ed);
656 add(sum.m, tmp, px->m);
657 sum.e = e1;
658 }
659 sum.prec = sum.m.bit_length();
660 sum.flag() = NotExact;
661 sum.normalize();
662 }
663
664
665
666 void
subtract(bigfloat & dif,const bigfloat & x,const bigfloat & y)667 subtract (bigfloat & dif, const bigfloat & x, const bigfloat & y)
668 {
669 const bigfloat *px, *py;
670 long log_x = x.e + x.prec, log_y = y.e + y.prec;
671 long log_dif = log_x - log_y;
672 long ed, e1, e2, i;
673
674 i = log_dif;
675 if (log_dif < 0) {
676 px = &y;
677 py = &x;
678 log_dif = -log_dif;
679 }
680 else {
681 px = &x;
682 py = &y;
683 }
684
685
686 e1 = px->e;
687 e2 = py->e;
688
689 int exp_error = check_overflow(ed, e1, -e2);
690 // ed = |e1 - e2|
691
692 if (exp_error) {
693 if (exp_error > 0)
694 lidia_error_handler("subtract", "exponent overflow");
695 else
696 lidia_error_handler("subtract", "exponent undeflow.");
697 }
698
699 if (bigfloat::rounding_mode != MP_EXACT)
700 if (log_dif > (bigfloat::binary_precision + rounding_bits)) {
701 dif.assign(*px);
702 if (i < 0)
703 dif.m.negate();
704 return;
705 }
706
707 if (ed > 0) {
708 bigint tmp(px->m);
709 shift_left(tmp, tmp, ed);
710 subtract(dif.m, tmp, py->m);
711 dif.e = e2;
712 }
713 else {
714 bigint tmp(py->m);
715 shift_left(tmp, tmp, -ed);
716 subtract(dif.m, px->m, tmp);
717 dif.e = e1;
718 }
719 if (i < 0)
720 dif.m.negate();
721 dif.prec = dif.m.bit_length();
722 dif.flag() = NotExact;
723 dif.normalize();
724 }
725
726
727
728 void
multiply(bigfloat & prod,const bigfloat & x,const bigfloat & y)729 multiply (bigfloat & prod, const bigfloat & x, const bigfloat & y)
730 {
731 long ex = x.e, ey = y.e;
732
733 multiply(prod.m, x.m, y.m);
734 prod.e = ex + ey;
735 int exp_error = check_overflow(prod.e, ex, ey);
736 if (exp_error) {
737 if (exp_error > 0)
738 lidia_error_handler("multiply", "exponent overflow");
739 else
740 lidia_error_handler("multiply", "exponent undeflow.");
741 }
742 prod.prec = prod.m.bit_length();
743 prod.flag() = NotExact;
744 prod.normalize();
745 }
746
747
748
749 void
multiply(bigfloat & prod,const bigfloat & x,long i)750 multiply (bigfloat & prod, const bigfloat & x, long i)
751 {
752 multiply(prod.m, x.m, i);
753 prod.e = x.e;
754 prod.prec = prod.m.bit_length();
755 prod.flag() = NotExact;
756 prod.normalize();
757 }
758
759
760
761 void
multiply(bigfloat & prod,long i,const bigfloat & x)762 multiply (bigfloat & prod, long i, const bigfloat & x)
763 {
764 multiply(prod.m, x.m, i);
765 prod.e = x.e;
766 prod.prec = prod.m.bit_length();
767 prod.flag() = NotExact;
768 prod.normalize();
769 }
770
771
772
773 void
square(bigfloat & c,const bigfloat & a)774 square (bigfloat & c, const bigfloat & a)
775 {
776 long ea = a.e;
777 square(c.m, a.m);
778 c.e = 2 * ea;
779 int exp_error = check_overflow(c.e, ea, ea);
780 if (exp_error) {
781 if (exp_error > 0)
782 lidia_error_handler("square", "exponent overflow");
783 else
784 lidia_error_handler("square", "exponent undeflow.");
785 }
786 c.prec = c.m.bit_length();
787 c.flag() = NotExact;
788 c.normalize();
789 }
790
791
792
793 void
divide(bigfloat & quot,const bigfloat & x,const bigfloat & y)794 divide (bigfloat & quot, const bigfloat & x, const bigfloat & y)
795 {
796 long ex = x.e, ey = y.e;
797 bigint tmp1(1), tmp2;
798 long t = bigfloat::binary_precision;
799 t += ((y.m.length() + 1) * bits_per_base_digit);
800 shift_left(tmp1, tmp1, t);
801 div_rem(tmp1, tmp2, tmp1, y.m);
802 multiply(quot.m, tmp1, x.m);
803 quot.e = -t + ex - ey;
804 quot.prec = quot.m.bit_length();
805 quot.flag() = NotExact;
806 quot.normalize();
807 }
808
809
810
811 void
divide(bigfloat & quot,const bigfloat & x,long i)812 divide (bigfloat & quot, const bigfloat & x, long i)
813 {
814 quot.assign(x);
815 quot.flag() = NotExact;
816 quot.normalize();
817 shift_left(quot.m, quot.m, bits_per_base_digit);
818 quot.e -= bits_per_base_digit;
819 divide(quot.m, quot.m, i);
820 quot.prec = quot.m.bit_length();
821 quot.normalize();
822 }
823
824
825
826 void
divide(bigfloat & quot,long i,const bigfloat & x)827 divide (bigfloat & quot, long i, const bigfloat & x)
828 {
829 long t = bigfloat::binary_precision;
830 bigint tmp(i);
831 t += ((x.m.length() + 1) * bits_per_base_digit);
832 shift_left(tmp, tmp, t);
833 div_rem(quot.m, tmp, tmp, x.m);
834 quot.e = -t - x.e;
835 quot.prec = quot.m.bit_length();
836 quot.flag() = NotExact;
837 quot.normalize();
838 }
839
840
841
842 void
divide(bigfloat & quot,long i,long j)843 divide (bigfloat & quot, long i, long j)
844 {
845 long t = bigfloat::binary_precision + bits_per_base_digit;
846 quot.m = i;
847 shift_left(quot.m, quot.m, t);
848 divide(quot.m, quot.m, j);
849 quot.e = -t;
850 quot.prec = quot.m.bit_length();
851 quot.flag() = NotExact;
852 quot.normalize();
853 }
854
855
856
857 void
ceil(bigfloat & y,const bigfloat & x)858 ceil (bigfloat & y, const bigfloat & x)
859 {
860 bigfloat fraction;
861 if (&y == &x) {
862 bigfloat tmp;
863 truncate(tmp, x);
864 subtract(fraction, x, tmp);
865 y.assign(tmp);
866 }
867 else {
868 truncate(y, x);
869 subtract(fraction, x, y);
870 }
871 if (fraction.is_gt_zero())
872 inc(y);
873 }
874
875
876
877 void
ceil(bigint & y,const bigfloat & x)878 ceil (bigint & y, const bigfloat & x)
879 {
880 truncate(y, x);
881
882 bigfloat fraction(y);
883 subtract(fraction, fraction, x);
884 fraction.negate();
885
886 if (fraction.is_gt_zero())
887 inc(y);
888 }
889
890
891
892 void
floor(bigint & y,const bigfloat & x)893 floor (bigint & y, const bigfloat & x)
894 {
895 truncate(y, x);
896
897 bigfloat fraction(y);
898 subtract(fraction, fraction, x);
899 fraction.negate();
900
901 if (fraction.is_lt_zero())
902 dec(y);
903 }
904
905
906
907 void
floor(bigfloat & y,const bigfloat & x)908 floor (bigfloat & y, const bigfloat & x)
909 {
910 bigfloat fraction;
911 if (&y == &x) {
912 bigfloat tmp;
913 truncate(tmp, x);
914 subtract(fraction, x, tmp);
915 y.assign(tmp);
916 }
917 else {
918 truncate(y, x);
919 subtract(fraction, x, y);
920 }
921 if (fraction.is_lt_zero())
922 dec(y);
923 }
924
925
926
927 void
round(bigint & y,const bigfloat & x)928 round (bigint & y, const bigfloat & x)
929 {
930 if (x.is_zero()) {
931 y.assign_zero();
932 return;
933 }
934
935 bigfloat half_plus_x(0.5);
936 add(half_plus_x, half_plus_x, x);
937 floor(y, half_plus_x);
938 }
939
940
941
942 void
round(bigfloat & y,const bigfloat & x)943 round (bigfloat & y, const bigfloat & x)
944 {
945 if (x.is_zero()) {
946 y.assign_zero();
947 return;
948 }
949
950 bigfloat half_plus_x(0.5);
951 add(half_plus_x, half_plus_x, x);
952 floor(y, half_plus_x);
953 }
954
955
956
957 void
truncate(bigint & y,const bigfloat & x)958 truncate (bigint & y, const bigfloat & x)
959 {
960 if (x.e >= 0)
961 shift_left(y, x.m, x.e);
962 else
963 shift_right(y, x.m, -x.e);
964 }
965
966
967
968 void
truncate(bigfloat & y,const bigfloat & x)969 truncate (bigfloat & y, const bigfloat & x)
970 {
971 if (x.e >= 0)
972 shift_left(y.m, x.m, x.e);
973 else
974 shift_right(y.m, x.m, -x.e);
975 y.e = 0;
976 y.prec = y.m.bit_length();
977 y.normalize();
978 }
979
980
981
982 int
leading_zeros() const983 bigfloat::leading_zeros () const
984 {
985 int l = m.bit_length() % bits_per_base_digit;
986
987 if (l == 0)
988 return l;
989 else
990 return bits_per_base_digit - l;
991 }
992
993
994
995 void
base_digit_normalize()996 bigfloat::base_digit_normalize ()
997 {
998 if (!m.is_zero()) {
999 int i = leading_zeros();
1000 shift_left(m, m, i);
1001 e -= i;
1002 prec += i;
1003 }
1004 }
1005
1006
1007
1008 void
normalize()1009 bigfloat::normalize ()
1010 {
1011 // exact numbers are not normalized;
1012 // MP_EXACT mode implies no rounding
1013 if (is_exact() || bigfloat::rounding_mode == MP_EXACT)
1014 return;
1015
1016 long dif = prec - bigfloat::binary_precision;
1017 bigint tmp;
1018
1019 // length of the number is greater than current precision
1020 if (dif > 0) {
1021 // find and store the last bit before cutting
1022 int addt;
1023 dif--;
1024 shift_right(tmp, m, dif);
1025 e += dif;
1026 addt = tmp.is_odd();
1027
1028 // cut
1029 tmp.divide_by_2();
1030 e++;
1031
1032 // if the last bit is equal to 1
1033 if (addt) {
1034 int lx = tmp.bit_length();
1035
1036 // round
1037 switch (bigfloat::rounding_mode) {
1038 case MP_RND:
1039 if (tmp.is_odd()) {
1040 if (tmp.is_lt_zero())
1041 tmp.dec();
1042 else
1043 tmp.inc();
1044 }
1045 break;
1046 case MP_RND_UP:
1047 if (tmp.is_gt_zero())
1048 tmp.inc();
1049 break;
1050 case MP_RND_DOWN:
1051 if (tmp.is_lt_zero())
1052 tmp.dec();
1053 break;
1054 }
1055 if (tmp.bit_length() > lx) {
1056 bigint tmp2;
1057 shift_right(tmp2, tmp, 1);
1058 tmp2.swap(tmp);
1059 e++;
1060 }
1061 }
1062 m.swap(tmp);
1063 }
1064 // length of the number is less than current precision; shift left
1065 else {
1066 dif = -dif;
1067 shift_left(m, m, dif);
1068 e -= dif;
1069 }
1070 prec = bigfloat::binary_precision;
1071 }
1072
1073
1074
1075 //
1076 // cuts the precision to l bits
1077 //
1078
1079 void
cut(long l)1080 bigfloat::cut (long l)
1081 {
1082 if (prec <= l) return;
1083 long dif = prec - l;
1084 shift_right(m, m, dif);
1085 e += dif;
1086 prec -= dif;
1087 }
1088
1089
1090
1091 void
cut(const bigfloat & x,long l)1092 bigfloat::cut (const bigfloat & x, long l)
1093 {
1094 flag() = x.flag();
1095 if (x.prec <= l) {
1096 m.assign(x.m);
1097 e = x.e;
1098 prec = x.prec;
1099 return;
1100 }
1101 long dif = x.prec - l;
1102 shift_right(m, x.m, dif);
1103 e = x.e + dif;
1104 prec = x.prec - dif;
1105 }
1106
1107
1108
1109 void
power(bigfloat & z,const bigfloat & x,long y)1110 power(bigfloat & z, const bigfloat & x, long y)
1111 {
1112 if (x.is_zero()) {
1113 z.assign_zero();
1114 return;
1115 }
1116 if (y == 0) {
1117 z.assign_one();
1118 return;
1119 }
1120
1121 // tmp stores the current 2^n-power of basis x
1122 bigfloat tmp(x);
1123 z.assign_one();
1124
1125 // use fast exponentiation for computing the power
1126 long yy = y;
1127
1128 // if y is negative use absolute value of y
1129 if (yy < 0)
1130 yy *= -1;
1131
1132 if (yy & 1)
1133 multiply(z, z, tmp);
1134 yy >>= 1;
1135
1136 while (yy > 0) {
1137 square(tmp, tmp);
1138 if (yy & 1)
1139 multiply(z, z, tmp);
1140 yy >>= 1;
1141 }
1142
1143 // if y is negative we have to invert the result
1144 if (y < 0)
1145 invert(z, z);
1146 }
1147
1148
1149
1150 void
power(bigfloat & z,const bigfloat & x,const bigfloat & y)1151 power(bigfloat & z, const bigfloat & x, const bigfloat & y)
1152 {
1153 if (x.is_zero()) {
1154 z.assign_zero();
1155 return;
1156 }
1157
1158 if (y.is_zero()) {
1159 z.assign_one();
1160 return;
1161 }
1162
1163 long yy = 0;
1164 y.longify(yy);
1165
1166 if (y == yy)
1167 power(z, x, yy);
1168
1169 else if (x.sign() > 0) {
1170 bigfloat tmp;
1171
1172 log(tmp, x);
1173 multiply(z, y, tmp);
1174 exp(z, z);
1175 }
1176
1177 else // i.e. if (x.sign() < 0) {
1178 lidia_error_handler("bigfloat",
1179 "power(bigfloat & z, const bigfloat & x, const bigfloat & y): x < 0 and y not an integer");
1180 }
1181
1182
1183
1184 void
sqrt(bigfloat & y,const bigfloat & x)1185 sqrt (bigfloat & y, const bigfloat & x)
1186 {
1187
1188 if (x.is_lt_zero())
1189 lidia_error_handler("bigfloat", "sqrt()::argument must be >= 0");
1190 if (x.is_zero())
1191 y.assign_zero();
1192 else {
1193 long t = bigfloat::binary_precision, l = bigfloat::digit_precision;
1194 long eps, ex, i, n, l1, l0, l2, l02;
1195 bigfloat p1, p2, p3;
1196
1197 p1.assign(x);
1198
1199 //
1200 // calculate the exponent ex of the result. If ex is odd
1201 // multiply the first approximation by 2
1202 //
1203
1204 ex = x.e + x.prec;
1205 eps = ex % 2;
1206 ex /= 2;
1207
1208 if (eps < 0) {
1209 eps += 2;
1210 ex--;
1211 }
1212
1213 //
1214 // normalize before calculating the start value for
1215 // the newton iteration. Set p1 = mantissa(x). Then
1216 // take the square root of the leading words and store
1217 // it in p2. Our approximation is at (bits_per_double - 1)
1218 // bits correct, so 1 + log2(digit_precision) steps are sufficient
1219 //
1220
1221 p1.e = -(p1.length() * bits_per_base_digit) + eps;
1222
1223 double beta = static_cast<double>(p1.m.most_significant_digit());
1224 beta /= max_base_digit_2;
1225 beta = std::sqrt((eps + 1) * beta);
1226 y.assign(beta);
1227
1228 l -= 2;
1229 n = 1 + static_cast<long>(std::log(static_cast<double>(l)) * INVLOG2);
1230
1231 //
1232 // Use increasing precision at each step. l1 is the number
1233 // of correct Digits at the current point. l2 ist the precision
1234 // to be set before the next iteration occurs. The code for
1235 // precision increasing is adapted from the PARI system.
1236 //
1237
1238 l1 = 1;
1239 l2 = 3;
1240 for (i = 1; i <= n; i++) {
1241 // from GP/PARI : start
1242
1243 l0 = l1 << 1;
1244 if (l0 <= l) {
1245 l2 += l1;
1246
1247 //
1248 // Use only the first l0 + 2 Digits of p3. Remember
1249 // that the newton iteration is self correcting
1250 //
1251
1252 l02 = l0 + 2;
1253 p3.cut(l02 * bits_per_base_digit);
1254
1255 //
1256 // Use only the first l0 + 2 Digits of y. Remember
1257 // that the newton iteration is self correcting
1258 //
1259
1260 y.cut(l02 * bits_per_base_digit);
1261 l1 = l0;
1262 }
1263 else {
1264 l2 += -l1 + l + 1;
1265 l1 = l + 1;
1266 }
1267 bigfloat::binary_precision = l2 * bits_per_base_digit;
1268
1269 // from GP/PARI : end
1270
1271 //
1272 // Use only the first l2 Digits of p1. Remember
1273 // that the newton iteration is self correcting
1274 //
1275
1276 if (p1.length() > l2) {
1277 p2.cut(p1, l2 * bits_per_base_digit);
1278 divide(p3, p2, y);
1279 }
1280 else
1281 divide(p3, p1, y);
1282 add(y, y, p3);
1283 y.e--;
1284 }
1285
1286 //
1287 // restore the precision and the exponent and
1288 // normalize the result
1289 //
1290
1291 bigfloat::binary_precision = t;
1292 y.e += ex;
1293 y.normalize();
1294 }
1295 }
1296
1297
1298
1299 void
randomize(const bigint & n,long f)1300 bigfloat::randomize (const bigint & n, long f)
1301 {
1302 random_generator rg;
1303 long ff;
1304
1305 assign(LiDIA::randomize(n));
1306
1307 if (f == 0)
1308 e = 0;
1309 else {
1310 rg >> ff;
1311 e = ff % f;
1312 if (ff & 1)
1313 e = -e;
1314 }
1315 }
1316
1317
1318
1319 long bigfloat::decimal_precision = static_cast<long>(std::ceil(2 * bits_per_base_digit * L2B10));
1320 long bigfloat::binary_precision = 5 * bits_per_base_digit;
1321 long bigfloat::digit_precision = 5;
1322
1323
1324
1325 void
set_precision(long t)1326 bigfloat::set_precision (long t)
1327 {
1328 if (t > 0) {
1329 bigfloat::decimal_precision = t;
1330 bigfloat::digit_precision = 3 + static_cast<long>(std::ceil(t / (L2B10 * bits_per_base_digit)));
1331 bigfloat::binary_precision = bits_per_base_digit * bigfloat::digit_precision;
1332 }
1333 else {
1334 bigfloat::decimal_precision = static_cast<long>(std::ceil(2*bits_per_base_digit * L2B10));
1335 bigfloat::binary_precision = 5 * bits_per_base_digit;
1336 bigfloat::digit_precision = 5;
1337 }
1338 }
1339
1340
1341
1342 int bigfloat::rounding_mode = MP_RND;
1343
1344
1345
1346 void
set_mode(int m)1347 bigfloat::set_mode (int m)
1348 {
1349 switch (m) {
1350 case MP_TRUNC:
1351 bigfloat::rounding_mode = MP_TRUNC;
1352 break;
1353 case MP_RND:
1354 bigfloat::rounding_mode = MP_RND;
1355 break;
1356 case MP_RND_UP:
1357 bigfloat::rounding_mode = MP_RND_UP;
1358 break;
1359 case MP_RND_DOWN:
1360 bigfloat::rounding_mode = MP_RND_DOWN;
1361 break;
1362 case MP_EXACT:
1363 bigfloat::rounding_mode = MP_EXACT;
1364 break;
1365 default:
1366 lidia_error_handler("bigfloat", "mode()::invalid rounding mode");
1367 break;
1368 }
1369 }
1370
1371
1372
1373 int
string_to_bigfloat(char * s,bigfloat & n)1374 string_to_bigfloat (char *s, bigfloat & n)
1375 {
1376 int mi, ei, eii, count;
1377 int j, l = strlen(s), expo = 0;
1378 char *mant, *exs, c;
1379
1380 //
1381 // allocate temporary space for the mantissa
1382 // and the short exponent; clear both arrays
1383 //
1384
1385 mant = new char[l + 2];
1386 exs = new char[10];
1387 for (mi = 0; mi <= l + 1; mi++)
1388 mant[mi] = '\0';
1389 for (ei = 0; ei < 10; ei++)
1390 exs[ei] = '\0';
1391
1392 //
1393 // mi -->counts the digits of the mantissa (including sign)
1394 // ei -->counts the digits of the exponent (including sign)
1395 // eii -->counts the digits after the decimal point
1396 // count -->is the counter on the array s
1397 //
1398
1399 mi = 0;
1400 ei = 0;
1401 eii = 0;
1402 count = 0;
1403
1404 // remove leading spaces
1405 c = s[count];
1406 while (isspace(c) || iscntrl(c)) {
1407 count++;
1408 c = s[count];
1409 }
1410
1411 // mantissa mign
1412 if (c == '-') {
1413 mant[mi] = c;
1414 count++;
1415 mi++;
1416 }
1417 else if (c == '+')
1418 count++;
1419
1420 // mart x
1421 c = s[count];
1422 while (isdigit(c)) {
1423 mant[mi] = c;
1424 count++;
1425 mi++;
1426 c = s[count];
1427 }
1428
1429 // radixpoint
1430 if (c == '.') {
1431 count++;
1432 c = s[count];
1433 }
1434
1435 // part y
1436 while (isdigit(c)) {
1437 mant[mi] = c;
1438 count++;
1439 mi++;
1440 eii--;
1441 c = s[count];
1442 }
1443
1444 // exponent
1445 if (c == 'E' || c == 'e') {
1446 count++;
1447 c = s[count];
1448
1449 // sign
1450 if (c == '-') {
1451 exs[ei] = c;
1452 count++;
1453 ei++;
1454 }
1455 else if (c == '+')
1456 count++;
1457
1458 // digits
1459 c = s[count];
1460 while (isdigit(c)) {
1461 exs[ei] = c;
1462 count++;
1463 ei++;
1464 c = s[count];
1465 }
1466 }
1467
1468 // take care of leading zeros
1469 size_t leading_zeros = strspn(mant, "0");
1470 if(mant[leading_zeros] == '\0') {
1471 if(leading_zeros > 0) {
1472 --leading_zeros;
1473 }
1474 else {
1475 // this implies mi == 0
1476 mant[0] = '0';
1477 mi = 1;
1478 }
1479 }
1480 mi -= leading_zeros;
1481
1482 // store mantissa and exponent in basis 10
1483 string_to_bigint(mant + leading_zeros, n.m);
1484 expo = static_cast<int>(atol(exs) + eii);
1485 n.e = expo;
1486
1487 // if exponent >= 0 we have an integer
1488 if (expo >= 0) {
1489 // calculate n * 10^expo
1490 long q = expo, r = q % log_max_pow_10;
1491 for (j = 0; j < r; j++)
1492 multiply(n.m, n.m, 10L);
1493 q -= r;
1494 while (q > 0) {
1495 multiply(n.m, n.m, max_pow_10);
1496 q -= log_max_pow_10;
1497 }
1498 n.e = 0;
1499 n.prec = n.m.bit_length();
1500 n.base_digit_normalize();
1501 n.flag() = Exact;
1502 }
1503 else {
1504 // we must convert a real
1505 bigint tmp(1);
1506 long h, q, r;
1507
1508 h = static_cast<long>((strlen(mant) + (-expo)) / L2B10);
1509 q = -expo;
1510 r = q % log_max_pow_10;
1511 for (j = 0; j < r; j++)
1512 multiply(tmp, tmp, 10L);
1513 q -= r;
1514 while (q > 0) {
1515 multiply(tmp, tmp, max_pow_10);
1516 q -= log_max_pow_10;
1517 }
1518 if (h < bigfloat::binary_precision)
1519 h = bigfloat::binary_precision;
1520 h <<= 1;
1521 shift_left(n.m, n.m, h);
1522 divide(n.m, n.m, tmp);
1523 n.e = -h;
1524 n.prec = n.m.bit_length();
1525 n.flag() = NotExact;
1526 n.normalize();
1527 }
1528 delete[] mant;
1529 delete[] exs;
1530 return l;
1531 }
1532
1533
1534
1535 int
bigfloat_to_string(const bigfloat & n,char * s)1536 bigfloat_to_string (const bigfloat & n, char *s)
1537 {
1538 if (n.is_zero()) {
1539 s[0] = '0';
1540 s[1] = '\0';
1541 return 1;
1542 }
1543
1544 //
1545 // Normalize the result, so that we have a uniform output
1546 //
1547
1548 bigfloat h(n);
1549 h.flag() = NotExact;
1550 h.normalize();
1551
1552 //
1553 // get the exponent of h and its sign
1554 //
1555
1556 long e1 = h.e, sign_exp = 0, e2;
1557 if (e1 == 0)
1558 return static_cast<int>(bigint_to_string(h.m, s));
1559 if (e1 > 0)
1560 sign_exp = 1;
1561 else
1562 sign_exp = -1;
1563
1564 // set e1 = abs(e1), e2 = e1 * log10(2)
1565 // case 1:
1566 //
1567 // e1 > 0 <= = > sign_exp = 1
1568 //
1569 // binary_mantissa(h) * 2^e1 = decimal_mantissa(h) * 10^e2, i.e
1570 // decimal_mantissa(h) = binary_mantissa(h) * 2^e1 / 10^e2
1571 //
1572 // e1< 0 <= = > sign_exp = -1
1573 //
1574 // binary_mantissa(h) * 2^e1 = decimal_mantissa(h) * 10^e2. Now
1575 // e1< 0 == > binary_mantissa(h) * 2^e1 = binary_mantissa(h) / 2^abs(e1)
1576 // e2< 0 == > decimal_mantissa(h) * 10^e2 = decimal_mantissa(h) / 10^abs(e2)
1577 //
1578 // == > binary_mantissa(h) / 2^abs(e1) = decimal_mantissa(h) / 10^abs(e2)
1579 // == > decimal_mantissa(h) = binary_mantissa(h) * 10^abs(e2) / 2^abs(e1)
1580 //
1581 //
1582
1583 e1 = sign_exp * e1;
1584 e2 = static_cast<long>(e1 * L2B10);
1585
1586 long q = e2, r = q % log_max_pow_10, i;
1587 if (sign_exp == 1) {
1588 shift_left(h.m, h.m, e1);
1589 for (i = 0; i < r; i++)
1590 divide(h.m, h.m, 10L);
1591 q -= r;
1592 while (q > 0) {
1593 divide(h.m, h.m, max_pow_10);
1594 q -= log_max_pow_10;
1595 }
1596 }
1597 else {
1598 for (i = 0; i < r; i++)
1599 multiply(h.m, h.m, 10L);
1600 q -= r;
1601 while (q > 0) {
1602 multiply(h.m, h.m, max_pow_10);
1603 q -= log_max_pow_10;
1604 }
1605 shift_right(h.m, h.m, e1);
1606 }
1607 h.e = sign_exp * e2;
1608
1609 // get the sign ms and convert the decimal_mantissa(h) to a string
1610 // Adjust the decimal exponent appropriately
1611 //
1612 long ms = 0;
1613 if (h.m.is_lt_zero()) {
1614 ms = 1;
1615 h.m.negate();
1616 }
1617 bigint_to_string(h.m, s);
1618 int sl = strlen(s);
1619 e1 = sl + sign_exp * e2;
1620
1621 //
1622 // Now we are going to cut the output to have at most
1623 // bigfloat::decimal_precision places. We do this fi
1624 // and only if the string has a length sl greater than
1625 // the current decimal precision.
1626 //
1627
1628 long cut;
1629 char ch, E[10];
1630
1631 i = 0;
1632 if (sl > bigfloat::decimal_precision) {
1633 //
1634 // round by taking the last two places in account. This
1635 // probably causes a carry (i = 1).
1636 //
1637 cut = bigfloat::decimal_precision;
1638 ch = s[cut + 1];
1639 if (ch > '5')
1640 s[cut] += (s[cut] > '5');
1641 ch = s[cut];
1642 if (ch >= '5')
1643 i = 1;
1644 else
1645 i = 0;
1646 s[cut] = '\0';
1647 if (i) {
1648 //
1649 // We have a carry which add stringbolically
1650 //
1651 cut--;
1652 while (cut >= 0 && i) {
1653 if (s[cut] == '9') {
1654 s[cut] = '0';
1655 cut--;
1656 i = 1;
1657 }
1658 else {
1659 s[cut] += 1;
1660 i = 0;
1661 }
1662 }
1663 if (cut == -1 && i) {
1664 int m, l = strlen(s) + 1;
1665 for (m = l; m > 0; m--)
1666 s[m] = s[m - 1];
1667 s[0] = '1';
1668 }
1669 }
1670 //
1671 // Adjust the exponent since there might have been a carry
1672 //
1673 sl = static_cast<int>(strlen(s) + i);
1674 e1 += (sl > bigfloat::decimal_precision);
1675 }
1676
1677 //
1678 // remove trailing zeroes to make ouput shorter
1679 //
1680
1681 i = sl - 1;
1682 while (s[i] == '0' && i > (e1 - 1)) {
1683 s[i] = '\0';
1684 i--;
1685 }
1686
1687 //
1688 // check if the decimal point lies at the end of the right side
1689 // If true, do not print it.
1690 //
1691
1692 if ((i + 1) == e1) {
1693 s[i + 1] = '\0';
1694 sl = static_cast<int>(i + 1);
1695 if (ms) {
1696 for (i = sl; i >= 0; i--)
1697 s[i + 1] = s[i];
1698 s[0] = '-';
1699 sl++;
1700 }
1701 return static_cast<int>(strlen(s));
1702 }
1703
1704 //
1705 // if the decimal point lies in the middle of the number
1706 // shift the fractional part of the number so that we
1707 // get a character to put the decimal point in it.
1708 // Else print 0. and the mantissa of the number. If we have
1709 // an exponent != 0, print it in schientific notation.
1710 //
1711 sl = strlen(s);
1712 if (e1 > 0 && e1 < sl) {
1713 for (i = sl; i >= e1; i--) {
1714 s[i + 1] = s[i];
1715 }
1716 s[e1] = '.';
1717 sl++;
1718 if (ms) {
1719 for (i = sl; i >= 0; i--)
1720 s[i + 1] = s[i];
1721 s[0] = '-';
1722 sl++;
1723 }
1724 return static_cast<int>(strlen(s));
1725 }
1726 else {
1727 for (i = sl + 3 - (!ms); i >= 3 - (!ms); i--)
1728 s[i] = s[i - 3 + (!ms)];
1729 if (ms) {
1730 s[0] = '-';
1731 s[1] = '0';
1732 s[2] = '.';
1733 sl += 3;
1734 }
1735 else {
1736 s[0] = '0';
1737 s[1] = '.';
1738 sl += 2;
1739 }
1740 if (e1 != 0) {
1741 s[sl] = 'e';
1742 s[++sl] = '\0';
1743 sprintf(E, "%ld", e1);
1744 strcat(s, E);
1745 }
1746 }
1747 return static_cast<int>(strlen(s));
1748 }
1749
1750
1751
1752 #ifndef HEADBANGER
1753
1754 int
check_overflow(long & z,long x,long y)1755 check_overflow(long &z, long x, long y)
1756 {
1757 if (x == 0) {
1758 z = y;
1759 return 0;
1760 }
1761 if (y == 0) {
1762 z = x;
1763 return 0;
1764 }
1765
1766 unsigned long uz = 0;
1767 int over_under = 0;
1768 int condition = (x > 0) * 2 + (y > 0);
1769 int sign = 0;
1770
1771 switch (condition) {
1772 case 3:
1773 // x > 0 and y > 0
1774 uz = x + y;
1775 break;
1776 case 2:
1777 // x > 0 and y <= 0
1778 if (x >= -y)
1779 uz = x - (-y);
1780 else {
1781 uz = (-y) - x;
1782 sign = 1;
1783 }
1784 // uz = |x + y|
1785 break;
1786 case 1:
1787 // x <= 0 and y > 0
1788 if (-x >= y) {
1789 uz = (-x) - y;
1790 sign = 1;
1791 }
1792 else
1793 uz = y - (-x);
1794 // uz = |x + y|
1795 break;
1796 case 0:
1797 // x <= 0 and y <= 0
1798 uz = (-x) + (-y);
1799 sign = 1;
1800 break;
1801 }
1802 z = static_cast<long>(uz);
1803 over_under = static_cast<int>(uz >> bits_per_base_digit_minus_1);
1804 // over_under will be 1 if the highest bit of uz is set,
1805 // i.e. if uz doesn't fit into a signed long. `sign' determines
1806 // whether this is an over- or under-flow.
1807 if (sign) {
1808 z = -z;
1809 over_under = -over_under;
1810 }
1811 return over_under;
1812 }
1813
1814 #endif // HEADBANGER
1815
1816
1817
1818 #ifdef LIDIA_NAMESPACE
1819 } // end of namespace LiDIA
1820 #endif
1821