1 /* file "inumbers.cc" */
3 /* Copyright (c) 1995 Stanford University
7 This software is provided under the terms described in
8 the "suif_copyright.h" include file. */
10 #include <suif_copyright.h>
13 * This file implements extended-precision integer arithmetic
14 * routines for the i_integer class.
17 #define _MODULE_ "libuseful.a"
19 #define RCS_BASE_FILE useful_inumbers_cc
21 #include <suif1/misc.h> /* for definitions of boolean and assert() only */
28 "$Id: inumbers.cc,v 1.2 1999/08/25 03:29:30 brm Exp $")
31 /*----------------------------------------------------------------------*
33 *----------------------------------------------------------------------*
38 The i_integer class is intended to model the mathematic concept of
39 integers, with some simple extensions for dealing with infinite and
40 undetermined quantities.
42 The values representable by the i_integer class include all the finite
43 integer numbers (subject to memory limitations of the machine that are
44 system dependent but large), plus four additional distinguishable
45 non-finite elements. There are of course various mathematical
46 concepts of heirarchies of infinite ordinals and cardinals, but those
47 concepts are not useful for the kinds of things we currently plan to
48 use this class for. The kinds of trans-finite concepts we do
49 represent are based on what the system will be used for.
51 These four new elements are ``positive infinity'', ``negative
52 infinity'', ``unsigned infinity'' , and ``undetermined''.
54 The purpose of ``unsigned infinity'' and ``undetermined'' is to make
55 multiplication and division defined over the whole class: ``unsigned
56 infinity'' essentially represents ``1/0'' and ``undetermined''
57 represents ``0/0''. Neither of these quantities may be compared with
58 ``greater than'' or ``less than'' comparisons with anything, and
59 ``undetermined'' may not be compared for equality with anything
62 The purpose of ``positive infinity'' and ``negative infinity'' is to
63 have upper and lower bounds to represent unlimited ranges. The
64 distinction between positive and negative must be made for this
65 purpose, but this wouldn't work with ``1/0'' because we want ``-1/0 =
66 1/-0 = 1/0'' by the axioms for ordinary division, so we cannot
67 distinguish sign in the result of dividing by zero. Hence ``unsigned
68 infinity'' is a different concept from either ``positive infinity'' or
69 ``negative infinity''.
71 The rules for addition, subtraction, negation, multiplication,
72 reciprication, and division involving these trans-finite elements are
74 (1) Any finite number added to or subtracted from a trans-finite
75 gives the same transfinite.
76 (2) Any finite number minus a transfinite gives the negation of the
78 (3) Negation of ``positive infinity'' gives ``negative infinity''
79 and vice-versa; negation of either of ``unsigned infinity'' or
80 ``undetermined'' gives back the same trans-finite.
81 (4) Multiplication of any trans-finite by a positive finite gives
82 back the same trans-finite; multiplication of any transfinite by
83 a negative finite gives the negation of the trans-finite;
84 multiplication of zero by any trans-finite gives back
86 (5) The reciprical of zero is ``unsigned infinity''; the reciprical
87 of ``unsigned infinity'', ``positive infinity'', and ``negative
88 infinity'' are all zero; and the reciprical of ``undetermined''
90 (6) Division is defined as multiplication of the numerator by the
91 reciprical of the denominator.
92 (7) Either of ``positive infinity'' or ``negative infinity'' added
93 to itself is the same trans-finite back; any other case of
94 addition of trans-finites gives ``undetermined''.
95 (8) ``positive infinity'' times itself or ``negative infinity''
96 times itself is ``positive infinity''; ``positive infinity''
97 times ``negative infinity'' is ``negative infinity''; ``unsigned
98 infinity'' times itself is ``unsigned infinity''; any other case
99 of multiplication by two trans-finites gives ``undetermined''.
105 The implementations of these functions have time complexity O(n) for
106 addition and subtraction, O(n^log_2(3)) for multiplication and base
107 change (including all the bit-wise operations, which are implemented
108 with base change), and O(n^2) for division, where ``n'' is the length
109 of the larger of the string operands (the log of the integer value).
112 *----------------------------------------------------------------------*
114 *----------------------------------------------------------------------*/
115 /*----------------------------------------------------------------------*
116 Begin Macro Definitions
117 *----------------------------------------------------------------------*/
119 /* The following is strangely defined because we only use it for
120 * machines on which LONG_MAX + LONG_MIN >= 0 and we want to avoid
121 * compiler warnings about overflow in constant expressions on other
122 * machines. NEG_INT_MIN is similar. */
124 #define NEG_LONG_MIN (((long)(LONG_MAX + LONG_MIN >= 0 ? 0 : LONG_MIN)) - \
126 #define NEG_INT_MIN (((int)(INT_MAX + INT_MIN >= 0 ? 0 : INT_MIN)) - INT_MIN)
128 /*----------------------------------------------------------------------*
129 End Macro Definitions
130 *----------------------------------------------------------------------*/
131 /*----------------------------------------------------------------------*
132 Begin Constant Declarations
133 *----------------------------------------------------------------------*/
135 /* CUTOFF must be at least 4 */
138 /*----------------------------------------------------------------------*
139 End Constant Declarations
140 *----------------------------------------------------------------------*/
141 /*----------------------------------------------------------------------*
142 Begin Type Declarations
143 *----------------------------------------------------------------------*/
148 unsigned long link_count
;
152 string_integer(unsigned long num_digits
)
155 the_digits
= new char[num_digits
+ 1];
160 assert(link_count
== 0);
165 enum binary_bit_ops
{ BBO_XOR
, BBO_AND
, BBO_IOR
};
167 /*----------------------------------------------------------------------*
168 End Type Declarations
169 *----------------------------------------------------------------------*/
170 /*----------------------------------------------------------------------*
171 Begin Private Global Variables
172 *----------------------------------------------------------------------*/
174 /*----------------------------------------------------------------------*
175 End Private Global Variables
176 *----------------------------------------------------------------------*/
177 /*----------------------------------------------------------------------*
178 Begin Private Function Declarations
179 *----------------------------------------------------------------------*/
181 static void add_link(string_integer
*the_si
);
182 static void cut_link(string_integer
*the_si
);
183 static string_integer
*add_string_integers(string_integer
*op1
,
184 string_integer
*op2
);
185 static string_integer
*multiply_string_integers(string_integer
*op1
,
186 string_integer
*op2
);
187 static string_integer
*div_string_integers(string_integer
*op1
,
188 string_integer
*op2
);
189 static string_integer
*mod_string_integers(string_integer
*op1
,
190 string_integer
*op2
);
191 static string_integer
*bitwise_op_string_integers(string_integer
*op1
,
194 static string_integer
*right_shift_string_integers(string_integer
*op1
,
195 string_integer
*op2
);
196 static boolean
string_integer_fits_long(string_integer
*the_si
);
197 static long long_from_string_integer(string_integer
*the_si
);
198 static string_integer
*string_integer_from_long(long the_long
);
199 static string_integer
*string_integer_from_unsigned_long(
200 unsigned long the_ulong
);
201 static void string_integer_to_binary(unsigned char **result
,
202 unsigned long *result_size
,
204 string_integer
*the_si
);
205 static string_integer
*binary_to_string_integer(unsigned char *bits
,
206 unsigned long bit_size
,
208 static boolean
string_magnitude_is_less(char *op1
, char *op2
,
209 unsigned long op1_len
,
210 unsigned long op2_len
, int offset
);
211 static void add_string_magnitudes(char *result
, char *op1
, char *op2
,
212 unsigned long op1_len
,
213 unsigned long op2_len
, int base
, int offset
);
214 static void add_to_string_magnitude(char *result
, char *op2
,
215 unsigned long result_len
,
216 unsigned long op2_len
, int base
,
218 static void subtract_string_magnitudes(char *result
, char *op1
, char *op2
,
219 unsigned long op1_len
,
220 unsigned long op2_len
, int base
,
222 static void multiply_string_magnitudes(char *result
, char *scratch
, char *op1
,
223 char *op2
, unsigned long op1_len
,
224 unsigned long op2_len
, int base
,
226 static void divide_string_magnitudes(char *div_result
, char *mod_result
,
227 char *op1
, char *op2
,
228 unsigned long op1_len
,
229 unsigned long op2_len
, int offset
);
230 static void justify_int_string(char *string
, unsigned long size
, int offset
);
231 static void base_convert(char *new_string
, char *scratch
, char *old_string
,
232 unsigned long old_size
, int old_base
, int new_base
,
233 int old_offset
, int new_offset
);
234 static int blow_up_factor(int old_base
, int new_base
);
235 static i_rational
read_digits_with_decimal_point(const char **location
,
238 /*----------------------------------------------------------------------*
239 End Private Function Declarations
240 *----------------------------------------------------------------------*/
241 /*----------------------------------------------------------------------*
242 Begin Public Method Implementations
243 *----------------------------------------------------------------------*/
245 i_integer::i_integer(const char *initial_string
, int base
)
247 the_tag
= IIT_UNDETERMINED
;
248 read(initial_string
, base
);
252 i_integer::~i_integer()
254 if (the_tag
== IIT_STRING_INT
)
255 cut_link(value
.si_val
);
259 boolean
i_integer::is_negative(void) const
264 return (value
.long_val
< 0);
266 return (value
.si_val
->is_negative
);
267 case IIT_NEG_INFINITY
:
274 boolean
i_integer::is_c_char(void) const
276 return (is_finite() && (*this >= CHAR_MIN
) && (*this <= CHAR_MAX
));
279 boolean
i_integer::is_c_unsigned_char(void) const
281 return (is_finite() && (*this >= 0) && (*this <= UCHAR_MAX
));
284 boolean
i_integer::is_c_signed_char(void) const
286 return (is_finite() && (*this >= SCHAR_MIN
) && (*this <= SCHAR_MAX
));
289 boolean
i_integer::is_c_short(void) const
291 return (is_finite() && (*this >= SHRT_MIN
) && (*this <= SHRT_MAX
));
294 boolean
i_integer::is_c_unsigned_short(void) const
296 return (is_finite() && (*this >= 0) && (*this <= USHRT_MAX
));
299 boolean
i_integer::is_c_int(void) const
301 return (is_finite() && (*this >= INT_MIN
) && (*this <= INT_MAX
));
304 boolean
i_integer::is_c_unsigned_int(void) const
306 return (is_finite() && (*this >= 0) && (*this <= UINT_MAX
));
309 boolean
i_integer::is_c_long(void) const
311 return (the_tag
== IIT_C_INT
);
314 boolean
i_integer::is_c_unsigned_long(void) const
316 return (is_finite() && (*this >= 0) && (*this <= ULONG_MAX
));
319 char i_integer::c_char(void) const
323 return (char)(c_unsigned_long());
325 return (char)(c_long());
328 unsigned char i_integer::c_unsigned_char(void) const
330 assert(is_c_unsigned_char());
331 return (unsigned char)(c_unsigned_long());
334 signed char i_integer::c_signed_char(void) const
336 assert(is_c_signed_char());
337 return (signed char)(c_long());
340 short i_integer::c_short(void) const
342 assert(is_c_short());
343 return (short)(c_long());
346 unsigned short i_integer::c_unsigned_short(void) const
348 assert(is_c_unsigned_short());
349 return (unsigned short)(c_unsigned_long());
352 int i_integer::c_int(void) const
355 return (int)(c_long());
358 unsigned int i_integer::c_unsigned_int(void) const
360 assert(is_c_unsigned_int());
361 return (unsigned int)(c_unsigned_long());
364 long i_integer::c_long(void) const
366 assert(the_tag
== IIT_C_INT
);
367 return value
.long_val
;
370 unsigned long i_integer::c_unsigned_long(void) const
372 assert(is_c_unsigned_long());
373 if (the_tag
== IIT_C_INT
)
374 return (long)(value
.long_val
);
376 assert(the_tag
== IIT_STRING_INT
);
377 unsigned long result
= 0;
378 char *digit_follow
= value
.si_val
->the_digits
;
379 while (*digit_follow
!= 0)
381 char this_digit
= *digit_follow
- '0';
382 assert(result
<= ((ULONG_MAX
- this_digit
) / 10));
384 result
+= this_digit
;
390 void i_integer::set_c_char(char new_value
)
392 set_c_long(new_value
);
395 void i_integer::set_c_unsigned_char(unsigned char new_value
)
397 if (new_value
> (unsigned long)LONG_MAX
)
398 set_c_unsigned_long(new_value
);
400 set_c_long(new_value
);
403 void i_integer::set_c_signed_char(signed char new_value
)
407 value
.long_val
= new_value
;
410 void i_integer::set_c_short(short new_value
)
414 value
.long_val
= new_value
;
417 void i_integer::set_c_unsigned_short(unsigned short new_value
)
419 if (new_value
> (unsigned long)LONG_MAX
)
420 set_c_unsigned_long(new_value
);
422 set_c_long(new_value
);
425 void i_integer::set_c_int(int new_value
)
429 value
.long_val
= new_value
;
432 void i_integer::set_c_unsigned_int(unsigned int new_value
)
434 if (new_value
> (unsigned long)LONG_MAX
)
435 set_c_unsigned_long(new_value
);
437 set_c_long(new_value
);
440 void i_integer::set_c_long(long new_value
)
444 value
.long_val
= new_value
;
447 void i_integer::set_c_unsigned_long(unsigned long new_value
)
450 if (new_value
<= (unsigned long)LONG_MAX
)
452 set_c_long(new_value
);
456 the_tag
= IIT_STRING_INT
;
457 value
.si_val
= string_integer_from_unsigned_long(new_value
);
460 void i_integer::set_integer(const i_integer
&new_value
)
462 if (&new_value
== this) return;
464 the_tag
= new_value
.the_tag
;
468 value
.long_val
= new_value
.value
.long_val
;
471 value
.si_val
= new_value
.value
.si_val
;
472 add_link(value
.si_val
);
479 void i_integer::clear(void)
481 if (the_tag
== IIT_STRING_INT
)
482 cut_link(value
.si_val
);
483 the_tag
= IIT_UNDETERMINED
;
486 i_integer
i_integer::written_length(int base
) const
488 assert((base
> 1) && (base
<= 36));
494 long remaining_value
= value
.long_val
;
495 if (remaining_value
== 0)
499 if (remaining_value
< 0)
502 while (remaining_value
!= 0)
504 long this_digit
= remaining_value
% base
;
505 remaining_value
/= base
;
514 while (remaining_value
!= 0)
516 remaining_value
/= base
;
526 return (strlen(value
.si_val
->the_digits
) +
527 (value
.si_val
->is_negative
? 1 : 0));
530 static char *scratch_buffer
= NULL
;
531 static unsigned long scratch_size
= 0;
533 char *this_digits
= value
.si_val
->the_digits
;
534 unsigned long decimal_size
= strlen(this_digits
);
536 unsigned long result_size
=
537 blow_up_factor(10, base
) * decimal_size
;
539 if ((scratch_buffer
== NULL
) || (scratch_size
< 10 * result_size
))
541 if (scratch_buffer
!= NULL
)
542 delete[] scratch_buffer
;
543 scratch_size
= 10 * result_size
;
544 scratch_buffer
= new char[scratch_size
];
547 base_convert(scratch_buffer
, &(scratch_buffer
[result_size
]),
548 this_digits
, decimal_size
, 10, base
, '0', 0);
550 char *follow_result
= scratch_buffer
;
551 char *result_end
= &(scratch_buffer
[result_size
- 1]);
552 while (*follow_result
== 0)
554 assert(follow_result
!= result_end
);
558 return ((result_end
- follow_result
) +
559 (value
.si_val
->is_negative
? 1 : 0));
561 case IIT_POS_INFINITY
:
563 case IIT_NEG_INFINITY
:
565 case IIT_SIGNLESS_INFINITY
:
567 case IIT_UNDETERMINED
:
575 void i_integer::write(char *location
, int base
) const
577 assert((base
> 1) && (base
<= 36));
584 sprintf(location
, "%ld", value
.long_val
);
588 char *follow_location
= location
;
589 long remaining_value
= value
.long_val
;
590 if (remaining_value
== 0)
592 *follow_location
= '0';
595 else if (remaining_value
< 0)
597 *follow_location
= '-';
599 while (remaining_value
!= 0)
601 long this_digit
= remaining_value
% base
;
602 remaining_value
/= base
;
608 this_digit
= -this_digit
;
610 *follow_location
= this_digit
+ '0';
612 *follow_location
= (this_digit
- 10) + 'a';
618 while (remaining_value
!= 0)
620 long this_digit
= remaining_value
% base
;
621 remaining_value
/= base
;
623 *follow_location
= this_digit
+ '0';
625 *follow_location
= (this_digit
- 10) + 'a';
629 *follow_location
= 0;
634 char *follow_location
= location
;
635 if (value
.si_val
->is_negative
)
637 sprintf(follow_location
, "-");
642 strcpy(follow_location
, value
.si_val
->the_digits
);
646 static char *scratch_buffer
= NULL
;
647 static unsigned long scratch_size
= 0;
649 char *this_digits
= value
.si_val
->the_digits
;
650 unsigned long decimal_size
= strlen(this_digits
);
652 unsigned long result_size
=
653 blow_up_factor(10, base
) * decimal_size
;
655 if ((scratch_buffer
== NULL
) ||
656 (scratch_size
< 10 * result_size
))
658 if (scratch_buffer
!= NULL
)
659 delete[] scratch_buffer
;
660 scratch_size
= 10 * result_size
;
661 scratch_buffer
= new char[scratch_size
];
664 base_convert(scratch_buffer
, &(scratch_buffer
[result_size
]),
665 this_digits
, decimal_size
, 10, base
, '0', 0);
667 char *follow_result
= scratch_buffer
;
668 char *result_end
= &(scratch_buffer
[result_size
- 1]);
669 while (*follow_result
== 0)
671 assert(follow_result
!= result_end
);
675 while (follow_result
!= result_end
)
677 int this_digit
= *follow_result
;
679 *follow_location
= this_digit
+ '0';
681 *follow_location
= (this_digit
- 10) + 'a';
686 *follow_location
= 0;
690 case IIT_POS_INFINITY
:
691 strcpy(location
, "+Inf");
693 case IIT_NEG_INFINITY
:
694 strcpy(location
, "-Inf");
696 case IIT_SIGNLESS_INFINITY
:
697 strcpy(location
, "Inf");
699 case IIT_UNDETERMINED
:
700 strcpy(location
, "??");
707 void i_integer::read(const char *location
, int base
)
709 assert((base
> 1) && (base
<= 36));
711 static char *scratch_buffer
= NULL
;
712 static unsigned long scratch_size
= 0;
716 const char *remaining_string
= location
;
717 boolean is_negative
= FALSE
;
719 while (isspace(*remaining_string
))
722 if (strncmp(remaining_string
, "+Inf", 4) == 0)
724 the_tag
= IIT_POS_INFINITY
;
727 else if (strncmp(remaining_string
, "-Inf", 4) == 0)
729 the_tag
= IIT_NEG_INFINITY
;
732 else if (strncmp(remaining_string
, "Inf", 3) == 0)
734 the_tag
= IIT_SIGNLESS_INFINITY
;
737 else if (strncmp(remaining_string
, "??", 4) == 0)
739 the_tag
= IIT_UNDETERMINED
;
743 if (*remaining_string
== '-')
749 while (isspace(*remaining_string
))
752 const char *follow_string
= remaining_string
;
754 boolean overflow
= FALSE
;
755 while (*follow_string
!= 0)
757 int this_digit
= *follow_string
;
758 if ((this_digit
>= '0') && (this_digit
<= '9'))
760 else if ((this_digit
>= 'a') && (this_digit
<= 'z'))
761 this_digit
-= ('a' - 10);
762 else if ((this_digit
>= 'A') && (this_digit
<= 'Z'))
763 this_digit
-= ('A' - 10);
767 if (this_digit
>= base
)
773 (LONG_MIN
/ base
) + (((LONG_MIN
% base
) < 0) ? 1 : 0))
779 if (this_long
< LONG_MIN
+ this_digit
)
784 this_long
-= this_digit
;
788 if (this_long
> LONG_MAX
/ base
)
794 if (this_long
> LONG_MAX
- this_digit
)
799 this_long
+= this_digit
;
808 value
.long_val
= this_long
;
812 while (*follow_string
!= 0)
814 int this_digit
= *follow_string
;
815 if ((this_digit
>= '0') && (this_digit
<= '9'))
817 else if ((this_digit
>= 'a') && (this_digit
<= 'z'))
818 this_digit
-= ('a' - 10);
819 else if ((this_digit
>= 'A') && (this_digit
<= 'Z'))
820 this_digit
-= ('A' - 10);
824 if (this_digit
>= base
)
830 unsigned long string_size
= follow_string
- remaining_string
;
831 unsigned long new_string_size
= string_size
;
833 new_string_size
= 2 * string_size
;
836 ((scratch_buffer
== NULL
) || (scratch_size
< 10 * new_string_size
)))
838 if (scratch_buffer
!= NULL
)
839 delete[] scratch_buffer
;
840 scratch_size
= 10 * new_string_size
;
841 scratch_buffer
= new char[scratch_size
];
844 string_integer
*new_si
= new string_integer(new_string_size
);
845 new_si
->is_negative
= is_negative
;
848 const char *follow_old
= remaining_string
;
849 char *follow_new
= new_si
->the_digits
;
850 const char *old_end
= &(remaining_string
[string_size
- 1]);
853 assert((*follow_old
>= '0') && (*follow_old
<= '9'));
854 *follow_new
= *follow_old
;
855 if (follow_old
== old_end
)
860 assert(follow_new
== &(new_si
->the_digits
[new_string_size
- 1]));
864 const char *follow_old
= remaining_string
;
865 char *follow_new
= scratch_buffer
;
866 const char *old_end
= &(remaining_string
[string_size
- 1]);
869 int this_digit
= *follow_old
;
870 if ((this_digit
>= '0') && (this_digit
<= '9'))
872 else if ((this_digit
>= 'a') && (this_digit
<= 'z'))
873 this_digit
-= ('a' - 10);
874 else if ((this_digit
>= 'A') && (this_digit
<= 'Z'))
875 this_digit
-= ('A' - 10);
879 *follow_new
= this_digit
;
880 if (follow_old
== old_end
)
885 assert(follow_new
== &(scratch_buffer
[string_size
- 1]));
887 base_convert(new_si
->the_digits
, &(scratch_buffer
[string_size
]),
888 scratch_buffer
, string_size
, base
, 10, 0, '0');
890 justify_int_string(new_si
->the_digits
, new_string_size
, '0');
892 the_tag
= IIT_STRING_INT
;
893 value
.si_val
= new_si
;
896 void i_integer::print(FILE *fp
, int base
) const
898 assert((base
> 1) && (base
<= 36));
905 fprintf(fp
, "%ld", value
.long_val
);
909 long remaining_value
= value
.long_val
;
910 if (remaining_value
== 0)
914 else if (remaining_value
< 0)
917 while (remaining_value
!= 0)
919 long this_digit
= remaining_value
% base
;
920 remaining_value
/= base
;
926 this_digit
= -this_digit
;
928 fputc(this_digit
+ '0', fp
);
930 fputc((this_digit
- 10) + 'a', fp
);
935 while (remaining_value
!= 0)
937 long this_digit
= remaining_value
% base
;
938 remaining_value
/= base
;
940 fputc(this_digit
+ '0', fp
);
942 fputc((this_digit
- 10) + 'a', fp
);
948 if (value
.si_val
->is_negative
)
952 fputs(value
.si_val
->the_digits
, fp
);
956 static char *scratch_buffer
= NULL
;
957 static unsigned long scratch_size
= 0;
959 char *this_digits
= value
.si_val
->the_digits
;
960 unsigned long decimal_size
= strlen(this_digits
);
962 unsigned long result_size
=
963 blow_up_factor(10, base
) * decimal_size
;
965 if ((scratch_buffer
== NULL
) ||
966 (scratch_size
< 10 * result_size
))
968 if (scratch_buffer
!= NULL
)
969 delete[] scratch_buffer
;
970 scratch_size
= 10 * result_size
;
971 scratch_buffer
= new char[scratch_size
];
974 base_convert(scratch_buffer
, &(scratch_buffer
[result_size
]),
975 this_digits
, decimal_size
, 10, base
, '0', 0);
977 char *follow_result
= scratch_buffer
;
978 char *result_end
= &(scratch_buffer
[result_size
- 1]);
979 while (*follow_result
== 0)
981 assert(follow_result
!= result_end
);
985 while (follow_result
!= result_end
)
987 int this_digit
= *follow_result
;
989 fputc(this_digit
+ '0', fp
);
991 fputc((this_digit
- 10) + 'a', fp
);
996 case IIT_POS_INFINITY
:
999 case IIT_NEG_INFINITY
:
1002 case IIT_SIGNLESS_INFINITY
:
1005 case IIT_UNDETERMINED
:
1013 boolean
i_integer::is_equal_to(const i_integer
&other
) const
1018 return ((other
.the_tag
== IIT_C_INT
) &&
1019 (value
.long_val
== other
.value
.long_val
));
1020 case IIT_STRING_INT
:
1021 return ((other
.the_tag
== IIT_STRING_INT
) &&
1022 (value
.si_val
->is_negative
==
1023 other
.value
.si_val
->is_negative
) &&
1024 (strcmp(value
.si_val
->the_digits
,
1025 other
.value
.si_val
->the_digits
) == 0));
1026 case IIT_POS_INFINITY
:
1027 return (other
.the_tag
== IIT_POS_INFINITY
);
1028 case IIT_NEG_INFINITY
:
1029 return (other
.the_tag
== IIT_NEG_INFINITY
);
1030 case IIT_SIGNLESS_INFINITY
:
1031 return (other
.the_tag
== IIT_SIGNLESS_INFINITY
);
1032 case IIT_UNDETERMINED
:
1040 boolean
i_integer::is_less_than(const i_integer
&other
) const
1045 switch (other
.the_tag
)
1048 return (value
.long_val
< other
.value
.long_val
);
1049 case IIT_STRING_INT
:
1050 return !(other
.value
.si_val
->is_negative
);
1051 case IIT_POS_INFINITY
:
1053 case IIT_NEG_INFINITY
:
1055 case IIT_SIGNLESS_INFINITY
:
1057 case IIT_UNDETERMINED
:
1063 case IIT_STRING_INT
:
1064 switch (other
.the_tag
)
1067 return value
.si_val
->is_negative
;
1068 case IIT_STRING_INT
:
1070 if (value
.si_val
->is_negative
&&
1071 !other
.value
.si_val
->is_negative
)
1075 else if ((!value
.si_val
->is_negative
) &&
1076 other
.value
.si_val
->is_negative
)
1081 char *this_digits
= value
.si_val
->the_digits
;
1082 char *other_digits
= other
.value
.si_val
->the_digits
;
1083 unsigned long this_count
= strlen(this_digits
);
1084 unsigned long other_count
= strlen(other_digits
);
1085 return string_magnitude_is_less(this_digits
, other_digits
,
1086 this_count
, other_count
,
1089 case IIT_POS_INFINITY
:
1091 case IIT_NEG_INFINITY
:
1093 case IIT_SIGNLESS_INFINITY
:
1095 case IIT_UNDETERMINED
:
1101 case IIT_POS_INFINITY
:
1103 case IIT_NEG_INFINITY
:
1104 switch (other
.the_tag
)
1108 case IIT_STRING_INT
:
1110 case IIT_POS_INFINITY
:
1112 case IIT_NEG_INFINITY
:
1114 case IIT_SIGNLESS_INFINITY
:
1116 case IIT_UNDETERMINED
:
1122 case IIT_SIGNLESS_INFINITY
:
1124 case IIT_UNDETERMINED
:
1132 boolean
i_integer::is_divisible_by(const i_integer
&other
) const
1134 return (div(other
) == 0);
1137 i_integer
i_integer::add(const i_integer
&other
) const
1142 switch (other
.the_tag
)
1146 long this_long
= value
.long_val
;
1147 long other_long
= other
.value
.long_val
;
1152 if (this_long
>= LONG_MIN
- other_long
)
1153 return i_integer(this_long
+ other_long
);
1157 return i_integer(this_long
+ other_long
);
1164 return i_integer(this_long
+ other_long
);
1168 if (this_long
<= LONG_MAX
- other_long
)
1169 return i_integer(this_long
+ other_long
);
1173 string_integer
*si1
= string_integer_from_long(this_long
);
1174 string_integer
*si2
= string_integer_from_long(other_long
);
1175 string_integer
*new_si
= add_string_integers(si1
, si2
);
1178 return i_integer(new_si
);
1180 case IIT_STRING_INT
:
1182 string_integer
*this_si
=
1183 string_integer_from_long(value
.long_val
);
1184 string_integer
*other_si
= other
.value
.si_val
;
1185 string_integer
*new_si
=
1186 add_string_integers(this_si
, other_si
);
1188 if (string_integer_fits_long(new_si
))
1190 long new_long
= long_from_string_integer(new_si
);
1192 return i_integer(new_long
);
1194 return i_integer(new_si
);
1196 case IIT_POS_INFINITY
:
1197 case IIT_NEG_INFINITY
:
1198 case IIT_SIGNLESS_INFINITY
:
1200 case IIT_UNDETERMINED
:
1206 case IIT_STRING_INT
:
1207 switch (other
.the_tag
)
1211 string_integer
*this_si
= value
.si_val
;
1212 string_integer
*other_si
=
1213 string_integer_from_long(other
.value
.long_val
);
1214 string_integer
*new_si
=
1215 add_string_integers(this_si
, other_si
);
1217 if (string_integer_fits_long(new_si
))
1219 long new_long
= long_from_string_integer(new_si
);
1221 return i_integer(new_long
);
1223 return i_integer(new_si
);
1225 case IIT_STRING_INT
:
1227 string_integer
*this_si
= value
.si_val
;
1228 string_integer
*other_si
= other
.value
.si_val
;
1229 string_integer
*new_si
=
1230 add_string_integers(this_si
, other_si
);
1231 if (this_si
->is_negative
!= other_si
->is_negative
)
1233 if (string_integer_fits_long(new_si
))
1235 long new_long
= long_from_string_integer(new_si
);
1237 return i_integer(new_long
);
1240 return i_integer(new_si
);
1242 case IIT_POS_INFINITY
:
1243 case IIT_NEG_INFINITY
:
1244 case IIT_SIGNLESS_INFINITY
:
1246 case IIT_UNDETERMINED
:
1252 case IIT_POS_INFINITY
:
1253 switch (other
.the_tag
)
1256 case IIT_STRING_INT
:
1257 case IIT_POS_INFINITY
:
1259 case IIT_NEG_INFINITY
:
1260 case IIT_SIGNLESS_INFINITY
:
1261 case IIT_UNDETERMINED
:
1267 case IIT_NEG_INFINITY
:
1268 switch (other
.the_tag
)
1271 case IIT_STRING_INT
:
1272 case IIT_NEG_INFINITY
:
1274 case IIT_POS_INFINITY
:
1275 case IIT_SIGNLESS_INFINITY
:
1276 case IIT_UNDETERMINED
:
1282 case IIT_SIGNLESS_INFINITY
:
1283 switch (other
.the_tag
)
1286 case IIT_STRING_INT
:
1288 case IIT_POS_INFINITY
:
1289 case IIT_NEG_INFINITY
:
1290 case IIT_SIGNLESS_INFINITY
:
1291 case IIT_UNDETERMINED
:
1297 case IIT_UNDETERMINED
:
1305 i_integer
i_integer::subtract(const i_integer
&other
) const
1307 i_integer other_negation
= other
.negate();
1308 return add(other_negation
);
1311 i_integer
i_integer::multiply(const i_integer
&other
) const
1316 switch (other
.the_tag
)
1320 long this_long
= value
.long_val
;
1321 long other_long
= other
.value
.long_val
;
1322 if ((this_long
== 0) || (other_long
== 0))
1323 return i_integer(0);
1328 if ((LONG_MAX
+ LONG_MIN
) >= 0)
1330 if (-this_long
<= LONG_MAX
/ -other_long
)
1331 return i_integer(this_long
* other_long
);
1335 if (this_long
> LONG_MAX
/ other_long
)
1336 return i_integer(this_long
* other_long
);
1341 if ((LONG_MAX
+ LONG_MIN
) >= 0)
1343 if (-this_long
<= NEG_LONG_MIN
/ other_long
)
1344 return i_integer(this_long
* other_long
);
1348 if (this_long
> LONG_MIN
/ other_long
)
1349 return i_integer(this_long
* other_long
);
1357 if ((LONG_MAX
+ LONG_MIN
) >= 0)
1359 if (this_long
<= NEG_LONG_MIN
/ -other_long
)
1360 return i_integer(this_long
* other_long
);
1364 if (other_long
> LONG_MIN
/ this_long
)
1365 return i_integer(this_long
* other_long
);
1370 if (this_long
<= LONG_MAX
/ other_long
)
1371 return i_integer(this_long
* other_long
);
1375 string_integer
*si1
= string_integer_from_long(this_long
);
1376 string_integer
*si2
= string_integer_from_long(other_long
);
1377 string_integer
*new_si
=
1378 multiply_string_integers(si1
, si2
);
1381 return i_integer(new_si
);
1383 case IIT_STRING_INT
:
1385 string_integer
*this_si
=
1386 string_integer_from_long(value
.long_val
);
1387 string_integer
*other_si
= other
.value
.si_val
;
1388 string_integer
*new_si
=
1389 multiply_string_integers(this_si
, other_si
);
1391 if (string_integer_fits_long(new_si
))
1393 long new_long
= long_from_string_integer(new_si
);
1395 return i_integer(new_long
);
1397 return i_integer(new_si
);
1399 case IIT_POS_INFINITY
:
1400 case IIT_NEG_INFINITY
:
1401 if (value
.long_val
== 0)
1403 else if (value
.long_val
< 0)
1404 return other
.negate();
1407 case IIT_SIGNLESS_INFINITY
:
1409 case IIT_UNDETERMINED
:
1415 case IIT_STRING_INT
:
1416 switch (other
.the_tag
)
1420 string_integer
*this_si
= value
.si_val
;
1421 string_integer
*other_si
=
1422 string_integer_from_long(other
.value
.long_val
);
1423 string_integer
*new_si
=
1424 multiply_string_integers(this_si
, other_si
);
1426 if (string_integer_fits_long(new_si
))
1428 long new_long
= long_from_string_integer(new_si
);
1430 return i_integer(new_long
);
1432 return i_integer(new_si
);
1434 case IIT_STRING_INT
:
1436 string_integer
*this_si
= value
.si_val
;
1437 string_integer
*other_si
= other
.value
.si_val
;
1438 string_integer
*new_si
=
1439 multiply_string_integers(this_si
, other_si
);
1440 if (string_integer_fits_long(new_si
))
1442 long new_long
= long_from_string_integer(new_si
);
1444 return i_integer(new_long
);
1446 return i_integer(new_si
);
1448 case IIT_POS_INFINITY
:
1449 case IIT_NEG_INFINITY
:
1451 return other
.negate();
1454 case IIT_SIGNLESS_INFINITY
:
1456 case IIT_UNDETERMINED
:
1462 case IIT_POS_INFINITY
:
1463 case IIT_NEG_INFINITY
:
1464 switch (other
.the_tag
)
1467 if (other
.value
.long_val
== 0)
1470 case IIT_STRING_INT
:
1471 if (other
.is_negative())
1475 case IIT_POS_INFINITY
:
1477 case IIT_NEG_INFINITY
:
1479 case IIT_SIGNLESS_INFINITY
:
1481 case IIT_UNDETERMINED
:
1487 case IIT_SIGNLESS_INFINITY
:
1488 switch (other
.the_tag
)
1491 if (other
.value
.long_val
== 0)
1494 case IIT_STRING_INT
:
1495 case IIT_POS_INFINITY
:
1496 case IIT_NEG_INFINITY
:
1497 case IIT_SIGNLESS_INFINITY
:
1499 case IIT_UNDETERMINED
:
1505 case IIT_UNDETERMINED
:
1513 i_integer
i_integer::div(const i_integer
&other
) const
1518 switch (other
.the_tag
)
1522 long this_long
= value
.long_val
;
1523 long other_long
= other
.value
.long_val
;
1524 if (other_long
== 0)
1533 result
.the_tag
= IIT_SIGNLESS_INFINITY
;
1539 return i_integer(0);
1540 if (other_long
== 1)
1541 return i_integer(this_long
);
1547 if ((LONG_MAX
+ LONG_MIN
) >= 0)
1549 return i_integer((-this_long
) / (-other_long
));
1553 if ((this_long
>= -LONG_MAX
) &&
1554 (other_long
>= -LONG_MAX
))
1556 return i_integer((-this_long
) /
1563 if ((LONG_MAX
+ LONG_MIN
) == 0)
1565 return i_integer(-((-this_long
) / other_long
));
1567 else if ((LONG_MAX
+ LONG_MIN
) > 0)
1569 if ((-this_long
) / other_long
<= NEG_LONG_MIN
)
1571 return i_integer(-((-this_long
) /
1577 if (this_long
>= -LONG_MAX
)
1579 return i_integer(-((-this_long
) /
1589 if ((LONG_MAX
+ LONG_MIN
) == 0)
1591 return i_integer(-(this_long
/ (-other_long
)));
1593 else if ((LONG_MAX
+ LONG_MIN
) > 0)
1595 if (this_long
/ (-other_long
) <= NEG_LONG_MIN
)
1597 return i_integer(-(this_long
/
1603 if (other_long
>= -LONG_MAX
)
1605 return i_integer(-(this_long
/
1612 return i_integer(this_long
/ other_long
);
1616 string_integer
*si1
= string_integer_from_long(this_long
);
1617 string_integer
*si2
= string_integer_from_long(other_long
);
1618 string_integer
*new_si
= div_string_integers(si1
, si2
);
1621 if (string_integer_fits_long(new_si
))
1623 long new_long
= long_from_string_integer(new_si
);
1625 return i_integer(new_long
);
1627 return i_integer(new_si
);
1629 case IIT_STRING_INT
:
1631 string_integer
*this_si
=
1632 string_integer_from_long(value
.long_val
);
1633 string_integer
*other_si
= other
.value
.si_val
;
1634 string_integer
*new_si
=
1635 div_string_integers(this_si
, other_si
);
1637 if (string_integer_fits_long(new_si
))
1639 long new_long
= long_from_string_integer(new_si
);
1641 return i_integer(new_long
);
1643 return i_integer(new_si
);
1645 case IIT_POS_INFINITY
:
1646 case IIT_NEG_INFINITY
:
1647 case IIT_SIGNLESS_INFINITY
:
1648 return i_integer(0);
1649 case IIT_UNDETERMINED
:
1655 case IIT_STRING_INT
:
1656 switch (other
.the_tag
)
1660 if (other
.value
.long_val
== 0)
1663 result
.the_tag
= IIT_SIGNLESS_INFINITY
;
1666 string_integer
*this_si
= value
.si_val
;
1667 string_integer
*other_si
=
1668 string_integer_from_long(other
.value
.long_val
);
1669 string_integer
*new_si
=
1670 div_string_integers(this_si
, other_si
);
1672 if (string_integer_fits_long(new_si
))
1674 long new_long
= long_from_string_integer(new_si
);
1676 return i_integer(new_long
);
1678 return i_integer(new_si
);
1680 case IIT_STRING_INT
:
1682 string_integer
*this_si
= value
.si_val
;
1683 string_integer
*other_si
= other
.value
.si_val
;
1684 string_integer
*new_si
=
1685 div_string_integers(this_si
, other_si
);
1686 if (string_integer_fits_long(new_si
))
1688 long new_long
= long_from_string_integer(new_si
);
1690 return i_integer(new_long
);
1692 return i_integer(new_si
);
1694 case IIT_POS_INFINITY
:
1695 case IIT_NEG_INFINITY
:
1696 case IIT_SIGNLESS_INFINITY
:
1697 return i_integer(0);
1698 case IIT_UNDETERMINED
:
1704 case IIT_POS_INFINITY
:
1705 case IIT_NEG_INFINITY
:
1706 switch (other
.the_tag
)
1709 if (other
.value
.long_val
== 0)
1712 case IIT_STRING_INT
:
1713 if (other
.is_negative())
1717 case IIT_POS_INFINITY
:
1718 case IIT_NEG_INFINITY
:
1719 case IIT_SIGNLESS_INFINITY
:
1720 case IIT_UNDETERMINED
:
1726 case IIT_SIGNLESS_INFINITY
:
1727 switch (other
.the_tag
)
1730 if (other
.value
.long_val
== 0)
1733 case IIT_STRING_INT
:
1735 case IIT_POS_INFINITY
:
1736 case IIT_NEG_INFINITY
:
1737 case IIT_SIGNLESS_INFINITY
:
1738 case IIT_UNDETERMINED
:
1744 case IIT_UNDETERMINED
:
1752 i_integer
i_integer::mod(const i_integer
&other
) const
1757 switch (other
.the_tag
)
1761 long this_long
= value
.long_val
;
1762 long other_long
= other
.value
.long_val
;
1763 if (other_long
== 0)
1767 return i_integer(0);
1768 if (other_long
== 1)
1769 return i_integer(0);
1775 if ((LONG_MAX
+ LONG_MIN
) >= 0)
1777 return i_integer(-((-this_long
) %
1782 if ((this_long
>= -LONG_MAX
) &&
1783 (other_long
>= -LONG_MAX
))
1785 return i_integer(-((-this_long
) %
1792 if ((LONG_MAX
+ LONG_MIN
) >= 0)
1794 return i_integer(-((-this_long
) % other_long
));
1798 if (this_long
>= -LONG_MAX
)
1800 return i_integer(-((-this_long
) %
1810 if ((LONG_MAX
+ LONG_MIN
) >= 0)
1812 return i_integer(this_long
% (-other_long
));
1816 if (other_long
>= -LONG_MAX
)
1818 return i_integer(this_long
%
1825 return i_integer(this_long
% other_long
);
1829 string_integer
*si1
= string_integer_from_long(this_long
);
1830 string_integer
*si2
= string_integer_from_long(other_long
);
1831 string_integer
*new_si
= mod_string_integers(si1
, si2
);
1834 if (string_integer_fits_long(new_si
))
1836 long new_long
= long_from_string_integer(new_si
);
1838 return i_integer(new_long
);
1840 return i_integer(new_si
);
1842 case IIT_STRING_INT
:
1844 string_integer
*this_si
=
1845 string_integer_from_long(value
.long_val
);
1846 string_integer
*other_si
= other
.value
.si_val
;
1847 string_integer
*new_si
=
1848 mod_string_integers(this_si
, other_si
);
1850 if (string_integer_fits_long(new_si
))
1852 long new_long
= long_from_string_integer(new_si
);
1854 return i_integer(new_long
);
1856 return i_integer(new_si
);
1858 case IIT_POS_INFINITY
:
1859 case IIT_NEG_INFINITY
:
1860 case IIT_SIGNLESS_INFINITY
:
1862 case IIT_UNDETERMINED
:
1868 case IIT_STRING_INT
:
1869 switch (other
.the_tag
)
1873 if (other
.value
.long_val
== 0)
1875 string_integer
*this_si
= value
.si_val
;
1876 string_integer
*other_si
=
1877 string_integer_from_long(other
.value
.long_val
);
1878 string_integer
*new_si
=
1879 mod_string_integers(this_si
, other_si
);
1881 if (string_integer_fits_long(new_si
))
1883 long new_long
= long_from_string_integer(new_si
);
1885 return i_integer(new_long
);
1887 return i_integer(new_si
);
1889 case IIT_STRING_INT
:
1891 string_integer
*this_si
= value
.si_val
;
1892 string_integer
*other_si
= other
.value
.si_val
;
1893 string_integer
*new_si
=
1894 mod_string_integers(this_si
, other_si
);
1895 if (string_integer_fits_long(new_si
))
1897 long new_long
= long_from_string_integer(new_si
);
1899 return i_integer(new_long
);
1901 return i_integer(new_si
);
1903 case IIT_POS_INFINITY
:
1904 case IIT_NEG_INFINITY
:
1905 case IIT_SIGNLESS_INFINITY
:
1907 case IIT_UNDETERMINED
:
1913 case IIT_POS_INFINITY
:
1914 case IIT_NEG_INFINITY
:
1915 case IIT_SIGNLESS_INFINITY
:
1916 case IIT_UNDETERMINED
:
1924 i_integer
i_integer::negate(void) const
1929 if ((LONG_MAX
+ LONG_MIN
) == 0)
1931 return i_integer(-(value
.long_val
));
1933 else if ((LONG_MAX
+ LONG_MIN
) > 0)
1935 long this_long
= value
.long_val
;
1936 if ((this_long
< 0) || (this_long
+ LONG_MIN
<= 0))
1937 return i_integer(-this_long
);
1938 string_integer
*new_si
= string_integer_from_long(this_long
);
1939 new_si
->is_negative
= TRUE
;
1940 return i_integer(new_si
);
1944 long this_long
= value
.long_val
;
1945 if ((this_long
> 0) || (this_long
+ LONG_MAX
>= 0))
1946 return i_integer(-this_long
);
1947 string_integer
*new_si
= string_integer_from_long(this_long
);
1948 new_si
->is_negative
= FALSE
;
1949 return i_integer(new_si
);
1951 case IIT_STRING_INT
:
1953 char *old_digits
= value
.si_val
->the_digits
;
1954 string_integer
*new_si
= new string_integer(strlen(old_digits
));
1955 strcpy(new_si
->the_digits
, old_digits
);
1956 new_si
->is_negative
= !(value
.si_val
->is_negative
);
1957 if (string_integer_fits_long(new_si
))
1959 long new_long
= long_from_string_integer(new_si
);
1961 return i_integer(new_long
);
1963 return i_integer(new_si
);
1965 case IIT_POS_INFINITY
:
1968 result
.the_tag
= IIT_NEG_INFINITY
;
1971 case IIT_NEG_INFINITY
:
1974 result
.the_tag
= IIT_POS_INFINITY
;
1977 case IIT_SIGNLESS_INFINITY
:
1978 case IIT_UNDETERMINED
:
1986 i_integer
i_integer::operator^(const i_integer
&other
) const
1991 switch (other
.the_tag
)
1995 long this_long
= value
.long_val
;
1996 long other_long
= other
.value
.long_val
;
1998 if ((this_long
>= 0) && (other_long
>= 0))
2000 return i_integer(((unsigned long)this_long
) ^
2001 ((unsigned long)other_long
));
2004 string_integer
*si1
= string_integer_from_long(this_long
);
2005 string_integer
*si2
= string_integer_from_long(other_long
);
2006 string_integer
*new_si
=
2007 bitwise_op_string_integers(si1
, si2
, BBO_XOR
);
2010 if (string_integer_fits_long(new_si
))
2012 long new_long
= long_from_string_integer(new_si
);
2014 return i_integer(new_long
);
2016 return i_integer(new_si
);
2018 case IIT_STRING_INT
:
2020 string_integer
*this_si
=
2021 string_integer_from_long(value
.long_val
);
2022 string_integer
*other_si
= other
.value
.si_val
;
2023 string_integer
*new_si
=
2024 bitwise_op_string_integers(this_si
, other_si
,
2027 if (string_integer_fits_long(new_si
))
2029 long new_long
= long_from_string_integer(new_si
);
2031 return i_integer(new_long
);
2033 return i_integer(new_si
);
2035 case IIT_POS_INFINITY
:
2036 case IIT_NEG_INFINITY
:
2037 case IIT_SIGNLESS_INFINITY
:
2042 case IIT_UNDETERMINED
:
2048 case IIT_STRING_INT
:
2049 switch (other
.the_tag
)
2053 string_integer
*this_si
= value
.si_val
;
2054 string_integer
*other_si
=
2055 string_integer_from_long(other
.value
.long_val
);
2056 string_integer
*new_si
=
2057 bitwise_op_string_integers(this_si
, other_si
,
2060 if (string_integer_fits_long(new_si
))
2062 long new_long
= long_from_string_integer(new_si
);
2064 return i_integer(new_long
);
2066 return i_integer(new_si
);
2068 case IIT_STRING_INT
:
2070 string_integer
*this_si
= value
.si_val
;
2071 string_integer
*other_si
= other
.value
.si_val
;
2072 string_integer
*new_si
=
2073 bitwise_op_string_integers(this_si
, other_si
,
2075 if (string_integer_fits_long(new_si
))
2077 long new_long
= long_from_string_integer(new_si
);
2079 return i_integer(new_long
);
2081 return i_integer(new_si
);
2083 case IIT_POS_INFINITY
:
2084 case IIT_NEG_INFINITY
:
2085 case IIT_SIGNLESS_INFINITY
:
2090 case IIT_UNDETERMINED
:
2096 case IIT_POS_INFINITY
:
2097 case IIT_NEG_INFINITY
:
2098 case IIT_SIGNLESS_INFINITY
:
2099 switch (other
.the_tag
)
2102 case IIT_STRING_INT
:
2103 if (other
.is_negative())
2107 case IIT_POS_INFINITY
:
2108 case IIT_NEG_INFINITY
:
2109 case IIT_SIGNLESS_INFINITY
:
2111 case IIT_UNDETERMINED
:
2117 case IIT_UNDETERMINED
:
2125 i_integer
i_integer::operator&(const i_integer
&other
) const
2130 switch (other
.the_tag
)
2134 long this_long
= value
.long_val
;
2135 long other_long
= other
.value
.long_val
;
2137 if ((this_long
>= 0) && (other_long
>= 0))
2139 return i_integer(((unsigned long)this_long
) &
2140 ((unsigned long)other_long
));
2143 string_integer
*si1
= string_integer_from_long(this_long
);
2144 string_integer
*si2
= string_integer_from_long(other_long
);
2145 string_integer
*new_si
=
2146 bitwise_op_string_integers(si1
, si2
, BBO_AND
);
2149 if (string_integer_fits_long(new_si
))
2151 long new_long
= long_from_string_integer(new_si
);
2153 return i_integer(new_long
);
2155 return i_integer(new_si
);
2157 case IIT_STRING_INT
:
2159 string_integer
*this_si
=
2160 string_integer_from_long(value
.long_val
);
2161 string_integer
*other_si
= other
.value
.si_val
;
2162 string_integer
*new_si
=
2163 bitwise_op_string_integers(this_si
, other_si
,
2166 if (string_integer_fits_long(new_si
))
2168 long new_long
= long_from_string_integer(new_si
);
2170 return i_integer(new_long
);
2172 return i_integer(new_si
);
2174 case IIT_POS_INFINITY
:
2175 case IIT_NEG_INFINITY
:
2176 case IIT_SIGNLESS_INFINITY
:
2181 case IIT_UNDETERMINED
:
2187 case IIT_STRING_INT
:
2188 switch (other
.the_tag
)
2192 string_integer
*this_si
= value
.si_val
;
2193 string_integer
*other_si
=
2194 string_integer_from_long(other
.value
.long_val
);
2195 string_integer
*new_si
=
2196 bitwise_op_string_integers(this_si
, other_si
,
2199 if (string_integer_fits_long(new_si
))
2201 long new_long
= long_from_string_integer(new_si
);
2203 return i_integer(new_long
);
2205 return i_integer(new_si
);
2207 case IIT_STRING_INT
:
2209 string_integer
*this_si
= value
.si_val
;
2210 string_integer
*other_si
= other
.value
.si_val
;
2211 string_integer
*new_si
=
2212 bitwise_op_string_integers(this_si
, other_si
,
2214 if (string_integer_fits_long(new_si
))
2216 long new_long
= long_from_string_integer(new_si
);
2218 return i_integer(new_long
);
2220 return i_integer(new_si
);
2222 case IIT_POS_INFINITY
:
2223 case IIT_NEG_INFINITY
:
2224 case IIT_SIGNLESS_INFINITY
:
2229 case IIT_UNDETERMINED
:
2235 case IIT_POS_INFINITY
:
2236 case IIT_NEG_INFINITY
:
2237 case IIT_SIGNLESS_INFINITY
:
2238 switch (other
.the_tag
)
2241 case IIT_STRING_INT
:
2242 if (other
.is_negative())
2246 case IIT_POS_INFINITY
:
2247 case IIT_NEG_INFINITY
:
2248 case IIT_SIGNLESS_INFINITY
:
2250 case IIT_UNDETERMINED
:
2256 case IIT_UNDETERMINED
:
2264 i_integer
i_integer::operator|(const i_integer
&other
) const
2269 switch (other
.the_tag
)
2273 long this_long
= value
.long_val
;
2274 long other_long
= other
.value
.long_val
;
2276 if ((this_long
>= 0) && (other_long
>= 0))
2278 return i_integer(((unsigned long)this_long
) |
2279 ((unsigned long)other_long
));
2282 string_integer
*si1
= string_integer_from_long(this_long
);
2283 string_integer
*si2
= string_integer_from_long(other_long
);
2284 string_integer
*new_si
=
2285 bitwise_op_string_integers(si1
, si2
, BBO_IOR
);
2288 if (string_integer_fits_long(new_si
))
2290 long new_long
= long_from_string_integer(new_si
);
2292 return i_integer(new_long
);
2294 return i_integer(new_si
);
2296 case IIT_STRING_INT
:
2298 string_integer
*this_si
=
2299 string_integer_from_long(value
.long_val
);
2300 string_integer
*other_si
= other
.value
.si_val
;
2301 string_integer
*new_si
=
2302 bitwise_op_string_integers(this_si
, other_si
,
2305 if (string_integer_fits_long(new_si
))
2307 long new_long
= long_from_string_integer(new_si
);
2309 return i_integer(new_long
);
2311 return i_integer(new_si
);
2313 case IIT_POS_INFINITY
:
2314 case IIT_NEG_INFINITY
:
2315 case IIT_SIGNLESS_INFINITY
:
2320 case IIT_UNDETERMINED
:
2326 case IIT_STRING_INT
:
2327 switch (other
.the_tag
)
2331 string_integer
*this_si
= value
.si_val
;
2332 string_integer
*other_si
=
2333 string_integer_from_long(other
.value
.long_val
);
2334 string_integer
*new_si
=
2335 bitwise_op_string_integers(this_si
, other_si
,
2338 if (string_integer_fits_long(new_si
))
2340 long new_long
= long_from_string_integer(new_si
);
2342 return i_integer(new_long
);
2344 return i_integer(new_si
);
2346 case IIT_STRING_INT
:
2348 string_integer
*this_si
= value
.si_val
;
2349 string_integer
*other_si
= other
.value
.si_val
;
2350 string_integer
*new_si
=
2351 bitwise_op_string_integers(this_si
, other_si
,
2353 if (string_integer_fits_long(new_si
))
2355 long new_long
= long_from_string_integer(new_si
);
2357 return i_integer(new_long
);
2359 return i_integer(new_si
);
2361 case IIT_POS_INFINITY
:
2362 case IIT_NEG_INFINITY
:
2363 case IIT_SIGNLESS_INFINITY
:
2368 case IIT_UNDETERMINED
:
2374 case IIT_POS_INFINITY
:
2375 case IIT_NEG_INFINITY
:
2376 case IIT_SIGNLESS_INFINITY
:
2377 switch (other
.the_tag
)
2380 case IIT_STRING_INT
:
2381 if (other
.is_negative())
2385 case IIT_POS_INFINITY
:
2386 case IIT_NEG_INFINITY
:
2387 case IIT_SIGNLESS_INFINITY
:
2389 case IIT_UNDETERMINED
:
2395 case IIT_UNDETERMINED
:
2403 i_integer
i_integer::operator~(void) const
2408 i_integer
i_integer::operator<<(const i_integer
&other
) const
2410 return (*this >> -other
);
2413 i_integer
i_integer::operator>>(const i_integer
&other
) const
2418 switch (other
.the_tag
)
2422 long this_long
= value
.long_val
;
2423 long other_long
= other
.value
.long_val
;
2425 if (other_long
== 0)
2429 else if (other_long
> 0)
2432 return (~((~(*this)) >> other
));
2435 (long)(sizeof(unsigned long) * CHAR_BIT
))
2437 return i_integer(((unsigned long)this_long
) >>
2447 if ((this_long
>= 0) &&
2449 -(long)(sizeof(unsigned long) * CHAR_BIT
)))
2451 unsigned long this_ulong
=
2452 (unsigned long)this_long
;
2453 unsigned long result
= (this_ulong
<< -other_long
);
2454 if ((result
>> -other_long
) == this_ulong
)
2459 string_integer
*si1
= string_integer_from_long(this_long
);
2460 string_integer
*si2
= string_integer_from_long(other_long
);
2461 string_integer
*new_si
=
2462 right_shift_string_integers(si1
, si2
);
2465 if (string_integer_fits_long(new_si
))
2467 long new_long
= long_from_string_integer(new_si
);
2469 return i_integer(new_long
);
2471 return i_integer(new_si
);
2473 case IIT_STRING_INT
:
2475 string_integer
*this_si
=
2476 string_integer_from_long(value
.long_val
);
2477 string_integer
*other_si
= other
.value
.si_val
;
2478 string_integer
*new_si
=
2479 right_shift_string_integers(this_si
, other_si
);
2481 if (string_integer_fits_long(new_si
))
2483 long new_long
= long_from_string_integer(new_si
);
2485 return i_integer(new_long
);
2487 return i_integer(new_si
);
2489 case IIT_POS_INFINITY
:
2494 case IIT_NEG_INFINITY
:
2495 if (value
.long_val
== 0)
2497 else if (is_negative())
2501 case IIT_SIGNLESS_INFINITY
:
2503 case IIT_UNDETERMINED
:
2509 case IIT_STRING_INT
:
2510 switch (other
.the_tag
)
2514 if (other
.value
.long_val
== 0)
2517 string_integer
*this_si
= value
.si_val
;
2518 string_integer
*other_si
=
2519 string_integer_from_long(other
.value
.long_val
);
2520 string_integer
*new_si
=
2521 right_shift_string_integers(this_si
, other_si
);
2523 if (string_integer_fits_long(new_si
))
2525 long new_long
= long_from_string_integer(new_si
);
2527 return i_integer(new_long
);
2529 return i_integer(new_si
);
2531 case IIT_STRING_INT
:
2533 string_integer
*this_si
= value
.si_val
;
2534 string_integer
*other_si
= other
.value
.si_val
;
2535 string_integer
*new_si
=
2536 right_shift_string_integers(this_si
, other_si
);
2537 if (string_integer_fits_long(new_si
))
2539 long new_long
= long_from_string_integer(new_si
);
2541 return i_integer(new_long
);
2543 return i_integer(new_si
);
2545 case IIT_POS_INFINITY
:
2550 case IIT_NEG_INFINITY
:
2555 case IIT_SIGNLESS_INFINITY
:
2557 case IIT_UNDETERMINED
:
2563 case IIT_POS_INFINITY
:
2564 case IIT_NEG_INFINITY
:
2565 case IIT_SIGNLESS_INFINITY
:
2566 switch (other
.the_tag
)
2569 case IIT_STRING_INT
:
2571 case IIT_POS_INFINITY
:
2573 case IIT_NEG_INFINITY
:
2575 case IIT_SIGNLESS_INFINITY
:
2577 case IIT_UNDETERMINED
:
2583 case IIT_UNDETERMINED
:
2592 void i_rational::reduce(void)
2594 if (the_numerator
.is_finite() && the_denominator
.is_finite())
2596 if (the_denominator
== 0)
2598 the_numerator
= i_signless_infinity();
2599 the_denominator
= 1;
2603 boolean result_negative
=
2604 (the_numerator
.is_negative() !=
2605 the_numerator
.is_negative());
2606 if (the_numerator
.is_negative())
2607 the_numerator
= -the_numerator
;
2608 if (the_denominator
.is_negative())
2609 the_denominator
= -the_denominator
;
2610 i_integer the_gcd
= ii_gcd(the_numerator
, the_denominator
);
2611 the_numerator
/= the_gcd
;
2612 the_denominator
/= the_gcd
;
2613 if (result_negative
)
2614 the_numerator
= -the_numerator
;
2619 if (the_numerator
.is_undetermined() ||
2620 the_denominator
.is_undetermined())
2622 the_denominator
= 1;
2624 else if (the_numerator
.is_finite())
2627 the_denominator
= 1;
2629 else if (the_denominator
.is_finite())
2631 if (the_denominator
== 0)
2633 the_numerator
= i_integer();
2634 the_denominator
= 1;
2636 else if (the_denominator
.is_negative())
2638 the_numerator
= -the_numerator
;
2639 the_denominator
= 1;
2643 the_denominator
= 1;
2648 the_numerator
= i_integer();
2649 the_denominator
= 1;
2654 i_integer
i_rational::written_length(int base
) const
2656 if (the_denominator
== 1)
2658 return the_numerator
.written_length(base
);
2662 return the_numerator
.written_length(base
) +
2663 the_denominator
.written_length(base
) + 1;
2667 void i_rational::write(char *location
, int base
) const
2669 the_numerator
.write(location
, base
);
2670 if (the_denominator
!= 1)
2672 unsigned long denominator_length
= strlen(location
);
2673 location
[denominator_length
] = '/';
2674 the_denominator
.write(&(location
[denominator_length
+ 1]), base
);
2678 void i_rational::read(const char *location
, int base
)
2680 const char *follow_string
= location
;
2682 i_rational new_numerator
=
2683 read_digits_with_decimal_point(&follow_string
, base
);
2685 while (isspace(*follow_string
))
2688 if (*follow_string
== '/')
2691 i_rational new_denominator
=
2692 read_digits_with_decimal_point(&follow_string
, base
);
2693 operator=(new_numerator
/ new_denominator
);
2697 operator=(new_numerator
);
2701 void i_rational::print(FILE *fp
, int base
) const
2703 the_numerator
.print(fp
, base
);
2704 if (the_denominator
!= 1)
2707 the_denominator
.print(fp
, base
);
2711 i_integer
i_rational::floor(void) const
2713 i_integer div
= the_numerator
/ the_denominator
;
2714 i_integer mod
= the_numerator
% the_denominator
;
2721 i_integer
i_rational::ceiling(void) const
2723 return -((-(*this)).floor());
2726 i_integer
i_rational::round(void) const
2728 return (*this + i_rational(1, 2)).floor();
2731 /*----------------------------------------------------------------------*
2732 End Public Method Implementations
2733 *----------------------------------------------------------------------*/
2734 /*----------------------------------------------------------------------*
2735 Begin Public Function Implementations
2736 *----------------------------------------------------------------------*/
2738 extern i_integer
i_positive_infinity(void)
2741 result
.the_tag
= IIT_POS_INFINITY
;
2745 extern i_integer
i_negative_infinity(void)
2748 result
.the_tag
= IIT_NEG_INFINITY
;
2752 extern i_integer
i_signless_infinity(void)
2755 result
.the_tag
= IIT_SIGNLESS_INFINITY
;
2759 extern i_integer
ii_gcd(const i_integer
&op1
, const i_integer
&op2
)
2771 i_integer temp_ii
= a
;
2784 i_integer new_a
= b
;
2790 extern i_integer
ii_gcd(const i_integer
&op1
, const i_integer
&op2
,
2791 i_integer
*coeff1
, i_integer
*coeff2
)
2809 i_integer temp_ii
= a
;
2820 * Invariant conditions:
2821 * op1 * n + op2 * m = a
2822 * op1 * p + op2 * q = b
2823 * where all variables are integers, op1 and op2 never change.
2825 * The values of a and b on the next iteration:
2829 * Which means that if we let:
2832 * new_p = n - p * (a div b)
2833 * new_q = m - q * (a div b)
2835 * Note that there is a recurrence between n and p, and one
2836 * between m and q, and both depend on the values of a and b
2837 * at each iteration. But it is not necessary to keep track
2838 * of q and m to calculate n and p (or equivalently, it would
2839 * not be necessary to keep track of n and p to calculate q
2840 * and m). Since we can derive m and q from the other
2841 * values, it is not necessary to calculate them at every
2842 * stage. So here we keep track of just n and p, and at the
2843 * end, when we want n and m, we have n and just derive m to
2844 * write into *coeff1 and *coeff2.
2849 *coeff2
= (a
- (op1
* n
)) / op2
;
2856 *coeff2
= (i_integer(1) - (op1
* p
)) / op2
;
2860 i_integer new_n
= p
;
2861 p
= n
- (p
* (a
/ b
));
2864 i_integer new_a
= b
;
2870 /*----------------------------------------------------------------------*
2871 End Public Function Implementations
2872 *----------------------------------------------------------------------*/
2873 /*----------------------------------------------------------------------*
2874 Begin Private Function Implementations
2875 *----------------------------------------------------------------------*/
2877 static void add_link(string_integer
*the_si
)
2879 if (the_si
->link_count
< ULONG_MAX
)
2880 ++the_si
->link_count
;
2883 static void cut_link(string_integer
*the_si
)
2885 if (the_si
->link_count
< ULONG_MAX
)
2886 --the_si
->link_count
;
2887 if (the_si
->link_count
== 0)
2891 static string_integer
*add_string_integers(string_integer
*op1
,
2892 string_integer
*op2
)
2894 char *this_digits
= op1
->the_digits
;
2895 char *other_digits
= op2
->the_digits
;
2896 unsigned long this_count
= strlen(this_digits
);
2897 unsigned long other_count
= strlen(other_digits
);
2899 boolean reversed
= FALSE
;
2901 if (string_magnitude_is_less(this_digits
, other_digits
, this_count
,
2905 char *temp_ptr
= this_digits
;
2906 this_digits
= other_digits
;
2907 other_digits
= temp_ptr
;
2908 unsigned long temp_count
= this_count
;
2909 this_count
= other_count
;
2910 other_count
= temp_count
;
2913 if (op1
->is_negative
!= op2
->is_negative
)
2915 string_integer
*new_si
= new string_integer(this_count
);
2917 new_si
->is_negative
= op2
->is_negative
;
2919 new_si
->is_negative
= op1
->is_negative
;
2920 subtract_string_magnitudes(new_si
->the_digits
, this_digits
,
2921 other_digits
, this_count
, other_count
, 10,
2923 justify_int_string(new_si
->the_digits
, this_count
, '0');
2924 if (new_si
->the_digits
[0] == 0)
2925 new_si
->is_negative
= FALSE
;
2930 string_integer
*new_si
= new string_integer(this_count
+ 1);
2931 new_si
->is_negative
= op1
->is_negative
;
2932 add_string_magnitudes(new_si
->the_digits
, this_digits
, other_digits
,
2933 this_count
, other_count
, 10, '0');
2935 if (*(new_si
->the_digits
) == '0')
2937 memmove(new_si
->the_digits
, &(new_si
->the_digits
[1]), this_count
);
2938 new_si
->the_digits
[this_count
] = 0;
2942 new_si
->the_digits
[this_count
+ 1] = 0;
2948 static string_integer
*multiply_string_integers(string_integer
*op1
,
2949 string_integer
*op2
)
2951 static unsigned long scratch_size
= 0;
2952 static char *scratch_buffer
= NULL
;
2954 char *this_digits
= op1
->the_digits
;
2955 char *other_digits
= op2
->the_digits
;
2956 unsigned long this_count
= strlen(this_digits
);
2957 unsigned long other_count
= strlen(other_digits
);
2959 if (this_count
< other_count
)
2961 char *temp_ptr
= this_digits
;
2962 this_digits
= other_digits
;
2963 other_digits
= temp_ptr
;
2964 unsigned long temp_count
= this_count
;
2965 this_count
= other_count
;
2966 other_count
= temp_count
;
2969 if (this_count
> ULONG_MAX
- other_count
)
2970 error_line(1, NULL
, "out of memory address space");
2971 unsigned long new_count
= this_count
+ other_count
;
2973 if (9 * new_count
> scratch_size
)
2975 if (scratch_buffer
!= NULL
)
2976 delete[] scratch_buffer
;
2977 scratch_buffer
= new char[9 * new_count
];
2978 scratch_size
= 9 * new_count
;
2981 string_integer
*new_si
= new string_integer(new_count
);
2982 new_si
->is_negative
= (op1
->is_negative
!= op2
->is_negative
);
2983 multiply_string_magnitudes(new_si
->the_digits
, scratch_buffer
, this_digits
,
2984 other_digits
, this_count
, other_count
, 10, '0');
2985 justify_int_string(new_si
->the_digits
, new_count
, '0');
2989 static string_integer
*div_string_integers(string_integer
*op1
,
2990 string_integer
*op2
)
2992 static unsigned long scratch_size
= 0;
2993 static char *scratch_buffer
= NULL
;
2995 char *this_digits
= op1
->the_digits
;
2996 char *other_digits
= op2
->the_digits
;
2997 unsigned long this_count
= strlen(this_digits
);
2998 unsigned long other_count
= strlen(other_digits
);
3000 if (this_count
< other_count
)
3001 return new string_integer(0);
3003 if (other_count
> scratch_size
)
3005 if (scratch_buffer
!= NULL
)
3006 delete[] scratch_buffer
;
3007 scratch_buffer
= new char[other_count
];
3008 scratch_size
= other_count
;
3011 string_integer
*new_si
=
3012 new string_integer((this_count
- other_count
) + 1);
3013 new_si
->is_negative
= (op1
->is_negative
!= op2
->is_negative
);
3014 divide_string_magnitudes(new_si
->the_digits
, scratch_buffer
, this_digits
,
3015 other_digits
, this_count
, other_count
, '0');
3016 justify_int_string(new_si
->the_digits
, (this_count
- other_count
) + 1,
3021 static string_integer
*mod_string_integers(string_integer
*op1
,
3022 string_integer
*op2
)
3024 static unsigned long scratch_size
= 0;
3025 static char *scratch_buffer
= NULL
;
3027 char *this_digits
= op1
->the_digits
;
3028 char *other_digits
= op2
->the_digits
;
3029 unsigned long this_count
= strlen(this_digits
);
3030 unsigned long other_count
= strlen(other_digits
);
3032 if (this_count
< other_count
)
3038 if ((this_count
- other_count
) + 1 > scratch_size
)
3040 if (scratch_buffer
!= NULL
)
3041 delete[] scratch_buffer
;
3042 scratch_size
= (this_count
- other_count
) + 1;
3043 scratch_buffer
= new char[scratch_size
];
3046 string_integer
*new_si
= new string_integer(other_count
);
3047 new_si
->is_negative
= op1
->is_negative
;
3048 divide_string_magnitudes(scratch_buffer
, new_si
->the_digits
, this_digits
,
3049 other_digits
, this_count
, other_count
, '0');
3050 justify_int_string(new_si
->the_digits
, other_count
, '0');
3054 static string_integer
*bitwise_op_string_integers(string_integer
*op1
,
3055 string_integer
*op2
,
3058 unsigned char *bits1
;
3059 unsigned char *bits2
;
3060 unsigned long size1
;
3061 unsigned long size2
;
3065 string_integer_to_binary(&bits1
, &size1
, &carry1
, op1
);
3066 string_integer_to_binary(&bits2
, &size2
, &carry2
, op2
);
3070 unsigned char *temp_bits
= bits1
;
3073 unsigned long temp_size
= size1
;
3076 int temp_carry
= carry1
;
3078 carry2
= temp_carry
;
3081 unsigned char *follow1
= &(bits1
[size1
- 1]);
3082 unsigned char *follow2
= &(bits2
[size2
- 1]);
3089 *follow1
= *follow1
^ *follow2
;
3090 if (follow2
== bits2
)
3099 *follow1
= *follow1
& *follow2
;
3100 if (follow2
== bits2
)
3109 *follow1
= *follow1
| *follow2
;
3110 if (follow2
== bits2
)
3119 assert(follow1
>= bits1
);
3136 string_integer
*result
=
3137 binary_to_string_integer(follow1
,
3138 (&(bits1
[size1
- 1]) - follow1
) + 1,
3145 static string_integer
*right_shift_string_integers(string_integer
*op1
,
3146 string_integer
*op2
)
3148 unsigned char *bits
;
3149 unsigned long bit_size
;
3152 string_integer_to_binary(&bits
, &bit_size
, &carry
, op1
);
3155 if (op2
->is_negative
)
3157 char *old_digits
= op2
->the_digits
;
3158 string_integer
*left_si
= new string_integer(strlen(old_digits
));
3159 strcpy(left_si
->the_digits
, old_digits
);
3160 left_si
->is_negative
= FALSE
;
3162 string_integer
*eight_si
= string_integer_from_long(8);
3163 string_integer
*div_si
= div_string_integers(left_si
, eight_si
);
3164 string_integer
*mod_si
= mod_string_integers(left_si
, eight_si
);
3168 assert(string_integer_fits_long(mod_si
));
3169 long mod_long
= long_from_string_integer(mod_si
);
3171 assert((mod_long
< 8) && (mod_long
>= 0));
3172 right_amount
= ((mod_long
== 0) ? 0 : 8 - mod_long
);
3174 if (!string_integer_fits_long(div_si
))
3175 error_line(1, NULL
, "out of memory address space");
3176 long add_digits
= long_from_string_integer(div_si
);
3181 if (add_digits
== LONG_MAX
)
3182 error_line(1, NULL
, "out of memory address space");
3186 assert(add_digits
> 0);
3187 unsigned long ulong_add
= add_digits
;
3188 if (bit_size
> LONG_MAX
- ulong_add
)
3189 error_line(1, NULL
, "out of memory address space");
3190 unsigned char *new_bits
= new unsigned char[bit_size
+ ulong_add
];
3191 strncpy((char *)new_bits
, (char *)bits
, bit_size
);
3192 memset(&(new_bits
[bit_size
]), 0, ulong_add
);
3195 bit_size
+= ulong_add
;
3199 string_integer
*eight_si
= string_integer_from_long(8);
3200 string_integer
*div_si
= div_string_integers(op2
, eight_si
);
3201 string_integer
*mod_si
= mod_string_integers(op2
, eight_si
);
3204 assert(string_integer_fits_long(mod_si
));
3205 right_amount
= long_from_string_integer(mod_si
);
3208 if (!string_integer_fits_long(div_si
))
3211 return string_integer_from_long((carry
== 1) ? -1 : 0);
3213 long cut_digits
= long_from_string_integer(div_si
);
3216 assert(cut_digits
>= 0);
3217 if (((unsigned long)cut_digits
) >= bit_size
)
3218 return string_integer_from_long((carry
== 1) ? -1 : 0);
3219 bit_size
-= cut_digits
;
3221 assert((right_amount
>= 0) && (right_amount
< 8));
3223 if (right_amount
!= 0)
3225 unsigned char *follow_bits
= bits
;
3226 unsigned char *bit_end
= &(bits
[bit_size
- 1]);
3227 unsigned char mask
= ~((~((unsigned)0)) << right_amount
);
3228 unsigned char temp_byte
= ((carry
== 1) ? mask
: 0);
3231 unsigned char old_byte
= *follow_bits
;
3233 (old_byte
>> right_amount
) |
3234 (temp_byte
<< (8 - right_amount
));
3235 temp_byte
= old_byte
& mask
;
3236 if (follow_bits
== bit_end
)
3242 string_integer
*result
= binary_to_string_integer(bits
, bit_size
, carry
);
3247 static boolean
string_integer_fits_long(string_integer
*the_si
)
3249 long long_total
= 0;
3251 char *digit_follow
= the_si
->the_digits
;
3252 if (the_si
->is_negative
)
3254 while (*digit_follow
!= 0)
3256 long this_digit
= *digit_follow
- '0';
3258 (((LONG_MIN
+ this_digit
) / 10) +
3259 ((((LONG_MIN
+ this_digit
) % 10) > 0) ? 1 : 0)))
3264 long_total
-= this_digit
;
3270 while (*digit_follow
!= 0)
3272 long this_digit
= *digit_follow
- '0';
3273 if (long_total
> ((LONG_MAX
- this_digit
) / 10))
3276 long_total
+= this_digit
;
3283 static long long_from_string_integer(string_integer
*the_si
)
3285 long long_total
= 0;
3287 char *digit_follow
= the_si
->the_digits
;
3288 if (the_si
->is_negative
)
3290 while (*digit_follow
!= 0)
3292 long this_digit
= *digit_follow
- '0';
3293 assert(long_total
>=
3294 (((LONG_MIN
+ this_digit
) / 10) +
3295 ((((LONG_MIN
+ this_digit
) % 10) > 0) ? 1 : 0)));
3297 long_total
-= this_digit
;
3303 while (*digit_follow
!= 0)
3305 long this_digit
= *digit_follow
- '0';
3306 assert(long_total
<= ((LONG_MAX
- this_digit
) / 10));
3308 long_total
+= this_digit
;
3315 static string_integer
*string_integer_from_long(long the_long
)
3317 static char buffer
[sizeof(unsigned long) * CHAR_BIT
/ 3 + 2];
3319 char *digit_follow
= buffer
;
3320 long remainder
= the_long
;
3323 while (remainder
< 0)
3325 long this_digit
= remainder
% 10;
3332 *digit_follow
= ((char)(-this_digit
)) + '0';
3338 while (remainder
> 0)
3340 *digit_follow
= ((char)(remainder
% 10)) + '0';
3346 unsigned long digits
= digit_follow
- buffer
;
3348 string_integer
*new_si
= new string_integer(digits
);
3349 new_si
->is_negative
= (the_long
< 0);
3351 char *follow_back
= new_si
->the_digits
;
3352 while (digit_follow
!= buffer
)
3355 *follow_back
= *digit_follow
;
3358 assert(follow_back
== &(new_si
->the_digits
[digits
]));
3363 static string_integer
*string_integer_from_unsigned_long(
3364 unsigned long the_ulong
)
3366 static char buffer
[sizeof(unsigned long) * CHAR_BIT
/ 3 + 2];
3368 char *digit_follow
= buffer
;
3369 unsigned long remainder
= the_ulong
;
3370 while (remainder
> 0)
3372 *digit_follow
= ((char)(remainder
% 10)) + '0';
3377 unsigned long digits
= digit_follow
- buffer
;
3379 string_integer
*new_si
= new string_integer(digits
);
3380 new_si
->is_negative
= FALSE
;
3382 char *follow_back
= new_si
->the_digits
;
3383 while (digit_follow
!= buffer
)
3386 *follow_back
= *digit_follow
;
3389 assert(follow_back
== &(new_si
->the_digits
[digits
]));
3394 static void string_integer_to_binary(unsigned char **result
,
3395 unsigned long *result_size
,
3397 string_integer
*the_si
)
3399 static char *buffer
= NULL
;
3400 static unsigned long buf_size
= 0;
3402 string_integer
*this_si
= the_si
;
3405 if (the_si
->is_negative
)
3407 string_integer
*one_si
= new string_integer(1);
3408 one_si
->is_negative
= FALSE
;
3409 one_si
->the_digits
[0] = '1';
3410 one_si
->the_digits
[1] = 0;
3411 string_integer
*sum_si
= add_string_integers(this_si
, one_si
);
3417 char *this_digits
= this_si
->the_digits
;
3418 unsigned long this_size
= strlen(this_digits
);
3420 *carry_bit
= (the_si
->is_negative
? 1 : 0);
3424 unsigned char *bits
= new unsigned char[1];
3425 if (the_si
->is_negative
)
3435 if ((buffer
== NULL
) || (buf_size
< this_size
* 20))
3439 buf_size
= this_size
* 20;
3440 buffer
= new char[buf_size
];
3443 base_convert(buffer
, &(buffer
[this_size
]), this_digits
, this_size
, 10,
3446 char *follow_buffer
= buffer
;
3447 char *end_buffer
= &(buffer
[this_size
- 1]);
3448 while ((*follow_buffer
== 0) && (follow_buffer
< end_buffer
))
3451 unsigned long final_size
= (end_buffer
- follow_buffer
) / 2 + 1;
3452 *result_size
= final_size
;
3453 unsigned char *bits
= new unsigned char[final_size
];
3455 unsigned char *follow_bits
= bits
;
3456 if (the_si
->is_negative
)
3458 if ((end_buffer
- follow_buffer
) % 2 == 0)
3460 unsigned char digit
= *follow_buffer
;
3461 *follow_bits
= ~digit
;
3462 if (follow_buffer
< end_buffer
)
3468 if (follow_buffer
< end_buffer
)
3472 unsigned char digit1
= *follow_buffer
;
3474 unsigned char digit2
= *follow_buffer
;
3475 *follow_bits
= ~((digit1
<< 4) | digit2
);
3476 if (follow_buffer
== end_buffer
)
3485 if ((end_buffer
- follow_buffer
) % 2 == 0)
3487 unsigned char digit
= *follow_buffer
;
3488 *follow_bits
= digit
;
3489 if (follow_buffer
< end_buffer
)
3495 if (follow_buffer
< end_buffer
)
3499 unsigned char digit1
= *follow_buffer
;
3501 unsigned char digit2
= *follow_buffer
;
3502 *follow_bits
= ((digit1
<< 4) | digit2
);
3503 if (follow_buffer
== end_buffer
)
3510 assert(follow_bits
== &(bits
[final_size
- 1]));
3514 static string_integer
*binary_to_string_integer(unsigned char *bits
,
3515 unsigned long bit_size
,
3518 assert(bit_size
> 0);
3520 static char *buffer
= NULL
;
3521 static unsigned long buf_size
= 0;
3523 if ((buffer
== NULL
) || (buf_size
< bit_size
* 20))
3527 buf_size
= bit_size
* 20;
3528 buffer
= new char[buf_size
];
3531 unsigned char *bit_follow
= bits
;
3532 unsigned char *bit_end
= &(bits
[bit_size
- 1]);
3533 char *buf_follow
= buffer
;
3538 unsigned char this_char
= *bit_follow
;
3539 *buf_follow
= (~(this_char
>> 4)) & 0xf;
3541 *buf_follow
= ((~this_char
) & 0xf);
3542 if (bit_follow
== bit_end
)
3552 unsigned char this_char
= *bit_follow
;
3553 *buf_follow
= (this_char
>> 4);
3555 *buf_follow
= (this_char
& 0xf);
3556 if (bit_follow
== bit_end
)
3562 assert(buf_follow
== &(buffer
[bit_size
* 2 - 1]));
3564 string_integer
*new_si
= new string_integer(bit_size
* 4);
3565 new_si
->is_negative
= (carry_bit
== 1);
3566 base_convert(new_si
->the_digits
, &(buffer
[bit_size
* 2]), buffer
,
3567 bit_size
* 2, 16, 10, 0, '0');
3568 justify_int_string(new_si
->the_digits
, bit_size
* 4, '0');
3571 string_integer
*neg_one_si
= new string_integer(1);
3572 neg_one_si
->is_negative
= TRUE
;
3573 neg_one_si
->the_digits
[0] = '1';
3574 neg_one_si
->the_digits
[1] = 0;
3575 string_integer
*sum_si
= add_string_integers(new_si
, neg_one_si
);
3577 cut_link(neg_one_si
);
3583 static boolean
string_magnitude_is_less(char *op1
, char *op2
,
3584 unsigned long op1_len
,
3585 unsigned long op2_len
, int offset
)
3587 char *new_op1
= op1
;
3588 char *new_op2
= op2
;
3589 unsigned long new_op1_len
= op1_len
;
3590 unsigned long new_op2_len
= op2_len
;
3592 while ((new_op1_len
> 0) && (*new_op1
== offset
))
3598 while ((new_op2_len
> 0) && (*new_op2
== offset
))
3604 if (new_op1_len
< new_op2_len
)
3606 if (new_op1_len
> new_op2_len
)
3608 return (strncmp(new_op1
, new_op2
, new_op1_len
) < 0);
3611 /* This assumes that op1_len >= op2_len. The result will have length
3613 static void add_string_magnitudes(char *result
, char *op1
, char *op2
,
3614 unsigned long op1_len
,
3615 unsigned long op2_len
, int base
, int offset
)
3617 assert((base
>= 2) && (base
- 1 <= CHAR_MAX
- offset
) &&
3618 (base
<= INT_MAX
/ 2));
3620 char *sum_follow
= &(result
[op1_len
+ 1]);
3621 char *op1_follow
= &(op1
[op1_len
]);
3622 char *op2_follow
= &(op2
[op2_len
]);
3625 while (op2_follow
!= op2
)
3630 remainder
+= (*op1_follow
- offset
) + (*op2_follow
- offset
);
3631 *sum_follow
= (remainder
% base
) + offset
;
3635 while ((op1_follow
!= op1
) && (remainder
!= 0))
3639 remainder
+= (*op1_follow
- offset
);
3640 *sum_follow
= (remainder
% base
) + offset
;
3644 while (op1_follow
!= op1
)
3648 *sum_follow
= *op1_follow
;
3651 assert(sum_follow
== &(result
[1]));
3652 assert((remainder
== 0) || (remainder
== 1));
3653 *result
= remainder
+ offset
;
3656 /* assumes that adding op2 will not result in overflow */
3657 static void add_to_string_magnitude(char *result
, char *op2
,
3658 unsigned long result_len
,
3659 unsigned long op2_len
, int base
,
3662 assert((base
>= 2) && (base
- 1 <= CHAR_MAX
- offset
) &&
3663 (base
<= INT_MAX
/ 2));
3665 char *sum_follow
= &(result
[result_len
]);
3666 char *op2_follow
= &(op2
[op2_len
]);
3668 char *op2_target
= op2
;
3669 while (((unsigned long)(op2_follow
- op2_target
)) > result_len
)
3671 assert(*op2_target
== offset
);
3676 while (op2_follow
!= op2_target
)
3680 remainder
+= (*sum_follow
- offset
) + (*op2_follow
- offset
);
3681 *sum_follow
= (remainder
% base
) + offset
;
3685 while (remainder
!= 0)
3687 assert(sum_follow
!= result
);
3689 remainder
+= (*sum_follow
- offset
);
3690 *sum_follow
= (remainder
% base
) + offset
;
3695 /* This assumes that op1 >= op2. The result will have length op1_len.
3697 static void subtract_string_magnitudes(char *result
, char *op1
, char *op2
,
3698 unsigned long op1_len
,
3699 unsigned long op2_len
, int base
,
3702 assert((base
>= 2) && (base
- 1 <= CHAR_MAX
- offset
));
3703 if (INT_MAX
+ INT_MIN
> 0)
3704 assert(base
<= NEG_INT_MIN
);
3705 else if (INT_MAX
+ INT_MIN
< 0)
3706 assert(-base
>= INT_MIN
);
3708 char *sum_follow
= &(result
[op1_len
]);
3709 char *op1_follow
= &(op1
[op1_len
]);
3710 char *op2_follow
= &(op2
[op2_len
]);
3711 assert(op1_len
>= op2_len
);
3714 while (op2_follow
!= op2
)
3719 remainder
+= (*op1_follow
- offset
) - (*op2_follow
- offset
);
3722 *sum_follow
= (remainder
+ base
) + offset
;
3727 *sum_follow
= remainder
+ offset
;
3732 while ((op1_follow
!= op1
) && (remainder
!= 0))
3736 remainder
+= (*op1_follow
- offset
);
3739 *sum_follow
= (remainder
+ base
) + offset
;
3744 *sum_follow
= remainder
+ offset
;
3749 while (op1_follow
!= op1
)
3753 *sum_follow
= *op1_follow
;
3756 assert(sum_follow
== &(result
[0]));
3757 assert(remainder
== 0);
3760 /* This assumes that op1_len >= op2_len and that the space in scratch
3761 * is >= (9 * op1_len). The result will have length op1_len +
3763 static void multiply_string_magnitudes(char *result
, char *scratch
, char *op1
,
3764 char *op2
, unsigned long op1_len
,
3765 unsigned long op2_len
, int base
,
3768 assert((base
>= 2) && (base
- 1 <= CHAR_MAX
- offset
));
3769 assert(base
<= INT_MAX
/ 2);
3770 assert(base
- 1 <= (INT_MAX
- 2 * (base
- 1))/(base
- 1));
3771 if (INT_MAX
+ INT_MIN
> 0)
3772 assert(base
<= NEG_INT_MIN
);
3773 else if (INT_MAX
+ INT_MIN
< 0)
3774 assert(-base
>= INT_MIN
);
3778 strncpy(result
, op1
, op1_len
);
3782 if (op1_len
<= CUTOFF
)
3784 char *result_start
= &(result
[op1_len
+ (op2_len
- 1)]);
3785 char *result_follow
= result_start
;
3786 char *op1_follow
= &(op1
[op1_len
- 1]);
3787 char *op2_follow
= &(op2
[op2_len
- 1]);
3789 int this_digit
= (*op2_follow
- offset
);
3790 if (this_digit
== 0)
3792 *result_follow
= offset
;
3798 carry
+= (*op1_follow
- offset
) * this_digit
;
3799 *result_follow
= ((char)(carry
% base
)) + offset
;
3801 assert(carry
<= base
- 2);
3802 if (op1_follow
== op1
)
3804 assert(result_follow
> result
);
3810 assert(result_follow
> result
);
3812 *result_follow
= carry
+ offset
;
3815 while (result_follow
> result
)
3818 *result_follow
= offset
;
3821 while (op2_follow
> op2
)
3824 assert(result_start
> result
);
3826 result_follow
= result_start
;
3827 op1_follow
= &(op1
[op1_len
- 1]);
3829 this_digit
= (*op2_follow
- offset
);
3830 if (this_digit
!= 0)
3834 carry
+= (*result_follow
- offset
);
3835 carry
+= (*op1_follow
- offset
) * this_digit
;
3836 *result_follow
= ((char)(carry
% base
)) + offset
;
3838 assert(carry
<= base
- 1);
3839 if (op1_follow
== op1
)
3841 assert(result_follow
> result
);
3847 assert(result_follow
> result
);
3849 *result_follow
= carry
+ offset
;
3856 unsigned long piece_length
=
3857 (op1_len
/ 2) + (((op1_len
% 2) == 0) ? 0 : 1);
3858 if (op2_len
<= piece_length
)
3861 // piece_length = roundup(op1_len/2)
3862 // Let's figure this out.
3864 // 1) partition op1 into (v1 x BASE^n + v2)
3865 // 2) multiply each part by op2.
3866 // 3) add them in the end.
3867 // example is base 10.
3876 // build a result with the right number of zeros.
3877 // assume there are op1_len + op2_len digits available
3878 // with a \0 already at the end?
3879 // I've tested this against bc on Factorial and FactorialSquared
3881 memset(result
, offset
, op1_len
+ op2_len
);
3882 multiply_string_magnitudes(&(result
[0]),
3885 op1_len
- piece_length
,
3886 op2_len
, base
, offset
);
3887 multiply_string_magnitudes(scratch
,
3888 &(scratch
[op2_len
+ piece_length
]),
3889 &(op1
[op1_len
- piece_length
]),
3891 piece_length
, op2_len
,
3893 add_to_string_magnitude(result
, scratch
,
3895 op2_len
+ piece_length
, base
,
3899 multiply_string_magnitudes(result
, scratch
, op1
, op2
,
3900 op1_len
- piece_length
,
3901 op2_len
- piece_length
, base
, offset
);
3902 multiply_string_magnitudes(&(result
[op1_len
+ op2_len
-
3903 (2 * piece_length
)]), scratch
,
3904 &(op1
[op1_len
- piece_length
]),
3905 &(op2
[op2_len
- piece_length
]),
3906 piece_length
, piece_length
, base
, offset
);
3907 add_string_magnitudes(&(scratch
[2 * piece_length
+ 2]),
3908 &(op1
[op1_len
- piece_length
]), op1
,
3909 piece_length
, op1_len
- piece_length
, base
,
3911 add_string_magnitudes(&(scratch
[3 * piece_length
+ 3]),
3912 &(op2
[op2_len
- piece_length
]), op2
,
3913 piece_length
, op2_len
- piece_length
, base
,
3915 multiply_string_magnitudes(scratch
, &(scratch
[4 * piece_length
+ 4]),
3916 &(scratch
[2 * piece_length
+ 2]),
3917 &(scratch
[3 * piece_length
+ 3]),
3918 piece_length
+ 1, piece_length
+ 1, base
,
3920 assert(scratch
[0] == offset
);
3921 subtract_string_magnitudes(&(scratch
[2 * piece_length
+ 2]),
3922 &(scratch
[1]), result
, 2 * piece_length
+ 1,
3923 op1_len
+ op2_len
- (2 * piece_length
),
3925 subtract_string_magnitudes(scratch
, &(scratch
[2 * piece_length
+ 2]),
3926 &(result
[op1_len
+ op2_len
-
3927 (2 * piece_length
)]),
3928 2 * piece_length
+ 1, 2 * piece_length
,
3930 add_to_string_magnitude(result
, scratch
,
3931 op1_len
+ op2_len
- piece_length
,
3932 2 * piece_length
+ 1, base
, offset
);
3936 /* This assumes that op1_len >= op2_len. div_result will have length
3937 * op1_len - op2_len + 1, and mod_result will have length op2_len. */
3938 static void divide_string_magnitudes(char *div_result
, char *mod_result
,
3939 char *op1
, char *op2
,
3940 unsigned long op1_len
,
3941 unsigned long op2_len
, int offset
)
3943 static char *factors
[9] =
3944 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
3945 static unsigned long factor_length
;
3946 static char *remainder
= NULL
;
3947 static char *alt_remainder
= NULL
;
3948 static unsigned long remainder_length
;
3950 if ((factors
[0] == NULL
) || (factor_length
< op1_len
+ 1))
3952 if (factors
[0] != NULL
)
3954 for (int index
= 0; index
< 9; ++index
)
3955 delete[] factors
[index
];
3957 factor_length
= op1_len
+ 1;
3958 for (int index
= 0; index
< 9; ++index
)
3959 factors
[index
] = new char[factor_length
];
3962 if ((remainder
== NULL
) || (remainder_length
< op1_len
))
3964 if (remainder
!= NULL
)
3967 delete[] alt_remainder
;
3969 remainder_length
= op1_len
;
3970 remainder
= new char[remainder_length
];
3971 alt_remainder
= new char[remainder_length
];
3974 for (int index
= 0; index
< 9; ++index
)
3976 if (op1_len
> op2_len
)
3977 memset(&(factors
[index
][op2_len
+ 1]), offset
, op1_len
- op2_len
);
3979 char *follow_factor
= &(factors
[index
][op2_len
]);
3980 char *follow_op2
= &(op2
[op2_len
- 1]);
3983 carry
+= (*follow_op2
- offset
) * (index
+ 1);
3984 *follow_factor
= ((char)(carry
% 10)) + offset
;
3988 if (follow_op2
== op2
)
3990 assert(follow_factor
> factors
[index
]);
3993 assert(follow_factor
== factors
[index
]);
3994 *follow_factor
= carry
+ offset
;
3997 memcpy(remainder
, op1
, op1_len
);
3999 char *follow_div
= div_result
;
4000 char *div_end
= &(div_result
[op1_len
- op2_len
]);
4001 unsigned long this_factor_length
= op1_len
+ 1;
4005 if (string_magnitude_is_less(remainder
, factors
[4], op1_len
,
4006 this_factor_length
, offset
))
4008 if (string_magnitude_is_less(remainder
, factors
[2], op1_len
,
4009 this_factor_length
, offset
))
4011 if (string_magnitude_is_less(remainder
, factors
[1], op1_len
,
4012 this_factor_length
, offset
))
4014 if (string_magnitude_is_less(remainder
, factors
[0],
4015 op1_len
, this_factor_length
,
4032 if (string_magnitude_is_less(remainder
, factors
[3], op1_len
,
4033 this_factor_length
, offset
))
4045 if (string_magnitude_is_less(remainder
, factors
[7], op1_len
,
4046 this_factor_length
, offset
))
4048 if (string_magnitude_is_less(remainder
, factors
[6], op1_len
,
4049 this_factor_length
, offset
))
4051 if (string_magnitude_is_less(remainder
, factors
[5],
4052 op1_len
, this_factor_length
,
4069 if (string_magnitude_is_less(remainder
, factors
[8], op1_len
,
4070 this_factor_length
, offset
))
4081 *follow_div
= this_digit
+ offset
;
4084 unsigned fact_len
= this_factor_length
;
4085 char *this_factor
= factors
[this_digit
- 1];
4086 while ((fact_len
> 1) && (*this_factor
== offset
))
4091 subtract_string_magnitudes(alt_remainder
, remainder
, this_factor
,
4092 op1_len
, fact_len
, 10, offset
);
4093 char *temp
= alt_remainder
;
4094 alt_remainder
= remainder
;
4098 if (follow_div
== div_end
)
4101 assert(this_factor_length
> op2_len
+ 1);
4102 --this_factor_length
;
4104 assert(this_factor_length
== op2_len
+ 1);
4105 for (unsigned long ul_index
= 0; ul_index
< op1_len
- op2_len
; ++ul_index
)
4106 assert(remainder
[ul_index
] == offset
);
4108 memcpy(mod_result
, &(remainder
[op1_len
- op2_len
]), op2_len
);
4111 static void justify_int_string(char *string
, unsigned long size
, int offset
)
4113 char *zero_follow
= string
;
4114 while ((zero_follow
+ 1 < &(string
[size
])) &&
4115 (*zero_follow
== offset
))
4119 unsigned long zero_count
= zero_follow
- string
;
4121 memmove(string
, zero_follow
, size
- zero_count
);
4122 string
[size
- zero_count
] = 0;
4125 /* This assumes that the space in scratch is >= (9 * <result size>). The
4126 * result will have length old_size * ceil(log_new_base(old_base)). */
4127 static void base_convert(char *new_string
, char *scratch
, char *old_string
,
4128 unsigned long old_size
, int old_base
, int new_base
,
4129 int old_offset
, int new_offset
)
4131 assert((new_base
>= 2) && (new_base
- 1 <= CHAR_MAX
- new_offset
));
4132 assert((old_base
>= 2) && (old_base
- 1 <= CHAR_MAX
- old_offset
));
4133 assert(old_base
<= LONG_MAX
/ old_base
);
4135 if (new_base
== old_base
)
4137 strcpy(new_string
, old_string
);
4144 /* set blow_up_factor = ceil(log_new_base(old_base)) */
4145 int blow_up
= blow_up_factor(old_base
, new_base
);
4149 long old_digit
= *old_string
- old_offset
;
4150 assert(old_digit
< old_base
);
4153 assert(old_string
[1] - old_offset
< old_base
);
4154 old_digit
*= old_base
;
4155 old_digit
+= (old_string
[1] - old_offset
);
4157 char *follow_new
= &(new_string
[old_size
* blow_up
- 1]);
4160 *follow_new
= ((char)(old_digit
% new_base
)) + new_offset
;
4161 old_digit
/= new_base
;
4162 if (follow_new
== new_string
)
4166 assert(old_digit
== 0);
4170 unsigned long right_size
= old_size
/ 2;
4171 unsigned long left_size
= old_size
- right_size
;
4172 char *s1
= &(scratch
[(right_size
+ 1) * blow_up
]);
4173 char *s2
= &(s1
[right_size
+ 1]);
4174 char *s3
= &(s2
[left_size
* blow_up
]);
4176 base_convert(s2
, s3
, old_string
, left_size
, old_base
, new_base
,
4177 old_offset
, new_offset
);
4179 /* set s1 = "1000...00" */
4180 s1
[0] = 1 + old_offset
;
4181 char *follow_s1
= s1
;
4182 char *end_s1
= &(s1
[right_size
]);
4183 while (follow_s1
!= end_s1
)
4186 *follow_s1
= old_offset
;
4189 base_convert(scratch
, s3
, s1
, right_size
+ 1, old_base
, new_base
,
4190 old_offset
, new_offset
);
4191 for (int index
= 0; index
< blow_up
; ++index
)
4192 assert(scratch
[index
] == new_offset
);
4193 multiply_string_magnitudes(new_string
, s3
, s2
, &(scratch
[blow_up
]),
4194 left_size
* blow_up
, right_size
* blow_up
,
4195 new_base
, new_offset
);
4196 base_convert(scratch
, &(scratch
[right_size
* blow_up
]),
4197 &(old_string
[left_size
]), right_size
, old_base
, new_base
,
4198 old_offset
, new_offset
);
4199 add_to_string_magnitude(new_string
, scratch
, old_size
* blow_up
,
4200 right_size
* blow_up
, new_base
, new_offset
);
4203 /* return ceil(log_new_base(old_base)) */
4204 static int blow_up_factor(int old_base
, int new_base
)
4207 int remainder
= old_base
- 1;
4208 while (remainder
> 0)
4210 remainder
/= new_base
;
4216 static i_rational
read_digits_with_decimal_point(const char **location
,
4219 i_integer
pre_decimal_point(*location
, base
);
4221 const char *follow_string
= *location
;
4223 while (isspace(*follow_string
))
4226 if (*follow_string
== '-')
4229 while (isspace(*follow_string
))
4232 while (*follow_string
!= 0)
4234 int this_digit
= *follow_string
;
4235 if ((this_digit
>= '0') && (this_digit
<= '9'))
4237 else if ((this_digit
>= 'a') && (this_digit
<= 'z'))
4238 this_digit
-= ('a' - 10);
4239 else if ((this_digit
>= 'A') && (this_digit
<= 'Z'))
4240 this_digit
-= ('A' - 10);
4244 if (this_digit
>= base
)
4250 if (*follow_string
!= '.')
4252 *location
= follow_string
;
4253 return pre_decimal_point
;
4256 const char *decimal_place
= follow_string
;
4260 while (*follow_string
!= 0)
4262 int this_digit
= *follow_string
;
4263 if ((this_digit
>= '0') && (this_digit
<= '9'))
4265 else if ((this_digit
>= 'a') && (this_digit
<= 'z'))
4266 this_digit
-= ('a' - 10);
4267 else if ((this_digit
>= 'A') && (this_digit
<= 'Z'))
4268 this_digit
-= ('A' - 10);
4272 if (this_digit
>= base
)
4278 *location
= follow_string
;
4280 if (follow_string
== decimal_place
+ 1)
4281 return pre_decimal_point
;
4283 i_integer
post_decimal_point(decimal_place
+ 1, base
);
4285 i_integer denominator
= 1;
4286 while (follow_string
> decimal_place
+ 1)
4288 denominator
*= base
;
4292 return i_rational(pre_decimal_point
) +
4293 i_rational(post_decimal_point
, denominator
);
4296 /*----------------------------------------------------------------------*
4297 End Private Function Implementations
4298 *----------------------------------------------------------------------*/