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