cvsuser 02/02/21 13:12:28
Modified: types bignum.c bignum.h
Log:
These might look like massive changes, but really it's just he imposition
of coding standards. The file still isn't entirely compliant, but is now
much more so.
Also changed:
o a few more comments
o BN_compare uses internal BN_comp to compare
o lost_digits behaviour is now correct (test harness modified to test
this).
All binary functions now pass all the tests in the basic standard.
Unary functions not yet tested, will be soon.
Revision Changes Path
1.4 +1165 -1127parrot/types/bignum.c
Index: bignum.c
===================================================================
RCS file: /home/perlcvs/parrot/types/bignum.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- bignum.c 21 Feb 2002 16:38:47 -0000 1.3
+++ bignum.c 21 Feb 2002 21:12:28 -0000 1.4
@@ -1,5 +1,5 @@
/*
- $Id: bignum.c,v 1.3 2002/02/21 16:38:47 ajgough Exp $
+ $Id: bignum.c,v 1.4 2002/02/21 21:12:28 ajgough Exp $
bignum.c -- A decimal arithmetic library for Perl and Parrot
@@ -121,17 +121,18 @@
Create a new BN. length is number of I<decimal> digits required.
=cut*/
-BIGNUM* BN_new(PINTD_ INTVAL length) {
+BIGNUM*
+BN_new(PINTD_ INTVAL length) {
BIGNUM* bn;
bn = (BIGNUM*)BN_alloc(PINT_ sizeof(BIGNUM));
- if (NULL == bn)
+ if (NULL == bn) {
BN_EXCEPT(PINT_ BN_INSUFFICIENT_STORAGE, "Cannot allocate new BigNum");
-
+ }
bn->nibs = 1 + length / BN_D_PER_NIB;
bn->buffer = (BN_NIB*)BN_alloc(PINT_ sizeof(BN_NIB) * bn->nibs);
- if (NULL == bn->buffer)
+ if (NULL == bn->buffer) {
BN_EXCEPT(PINT_ BN_INSUFFICIENT_STORAGE, "Cannot allocate new BigNum");
-
+ }
bn->sign = 0;
bn->expn = 0;
bn->digits = 1;
@@ -145,18 +146,21 @@
Grows in so that it can contain length I<decimal> digits.
=cut*/
-void BN_grow(PINTD_ BIGNUM *in, INTVAL length) {
+void
+BN_grow(PINTD_ BIGNUM *in, INTVAL length) {
assert(in != NULL);
- if (length <= in->nibs * BN_D_PER_NIB)
+ if (length <= in->nibs * BN_D_PER_NIB) {
return;
-
- if (length > BN_MAX_DIGITS)
+ }
+ if (length > BN_MAX_DIGITS) {
BN_EXCEPT(PINT_ BN_OVERFLOW, "Attempt to grow BIGNUM beyond limits");
-
+ }
in->nibs = 1+ length / BN_D_PER_NIB;
- in->buffer = (BN_NIB*)BN_realloc(PINT_ in->buffer, sizeof(BN_NIB)* (in->nibs) );
- if (NULL==in->buffer)
+ in->buffer = (BN_NIB*)BN_realloc(PINT_ in->buffer,
+ sizeof(BN_NIB)* (in->nibs) );
+ if (NULL==in->buffer) {
BN_EXCEPT(PINT_ BN_INSUFFICIENT_STORAGE, "Cannot grow BIGNUM");
+ }
return;
}
@@ -165,7 +169,8 @@
Frees the memory used by the BIGNUM.
=cut*/
-void BN_destroy(PINTD_ BIGNUM *bn) {
+void
+BN_destroy(PINTD_ BIGNUM *bn) {
assert(bn!=NULL);
BN_free(PINT_ bn->buffer);
@@ -186,15 +191,18 @@
I<digits> is also updated.
=cut*/
-INTVAL BN_set_digit(PINT_ BIGNUM* bn, INTVAL pos, INTVAL value) {
+INTVAL
+BN_set_digit(PINT_ BIGNUM* bn, INTVAL pos, INTVAL value) {
assert(bn != NULL);
- if (pos > bn->nibs * BN_D_PER_NIB)
+ if (pos > bn->nibs * BN_D_PER_NIB) {
BN_grow(bn, pos);
+ }
assert(value < 10);
assert(value > -1);
BN_setd(bn, pos, value);
- if (bn->digits < pos+1)
+ if (bn->digits < pos+1) {
bn->digits = pos+1;
+ }
return value;
}
@@ -204,7 +212,8 @@
bounds.
=cut*/
-INTVAL BN_get_digit(PINTD_ BIGNUM* bn, INTVAL pos) {
+INTVAL
+BN_get_digit(PINTD_ BIGNUM* bn, INTVAL pos) {
assert(bn != NULL);
if (pos > bn->digits || pos < 0) return -1;
return BN_getd(bn, pos);
@@ -215,7 +224,8 @@
Copies two into one, returning one for convenience.
=cut*/
-BIGNUM* BN_copy(PINTD_ BIGNUM* one, BIGNUM* two) {
+BIGNUM*
+BN_copy(PINTD_ BIGNUM* one, BIGNUM* two) {
assert(one != NULL); assert(two != NULL);
BN_grow(PINT_ two, one->digits);
@@ -234,7 +244,8 @@
those required to store a single integer into a bignum.
=cut*/
-BIGNUM* BN_new_from_int(PINTD_ INTVAL value) {
+BIGNUM*
+BN_new_from_int(PINTD_ INTVAL value) {
BIGNUM *new;
int i, current;
new = BN_new(PINT_ BN_D_PER_INT);
@@ -259,7 +270,8 @@
Dump the bignum for testing (should the to_*_string versions be broked).
=cut*/
-void BN_PRINT_DEBUG (BIGNUM *bn, char* mesg) {
+void
+BN_PRINT_DEBUG (BIGNUM *bn, char* mesg) {
INTVAL i;
printf("%s: nibs %i digits %i sign %i expn %i \n",mesg,
bn->nibs, bn->digits, bn->sign, bn->expn);
@@ -276,7 +288,8 @@
Throw `exception'. Should be accessed via a BN_EXCEPT macro
=cut */
-void BN_exception(PINTD_ BN_EXCEPTIONS exception, char* message) {
+void
+BN_exception(PINTD_ BN_EXCEPTIONS exception, char* message) {
printf("Exception %d %s\n", exception, message);
exit(0);
}
@@ -301,14 +314,17 @@
=cut*/
-INTVAL BN_to_scientific_string(PINTD_ BIGNUM*bn, char **dest) {
+INTVAL
+BN_to_scientific_string(PINTD_ BIGNUM*bn, char **dest) {
BN_to_scieng_string(PINT_ bn, dest, 0);
}
-INTVAL BN_to_engineering_string(PINTD_ BIGNUM*bn, char **dest) {
+INTVAL
+BN_to_engineering_string(PINTD_ BIGNUM*bn, char **dest) {
BN_to_scieng_string(PINT_ bn, dest, 1);
}
-INTVAL BN_to_scieng_string(PINTD_ BIGNUM* bn, char **dest, int eng) {
+INTVAL
+BN_to_scieng_string(PINTD_ BIGNUM* bn, char **dest, int eng) {
char* cur;
INTVAL adj_exp = 0; /* as bn->expn is relative to 0th digit */
INTVAL cur_dig = 0;
@@ -421,7 +437,8 @@
Does not yet check for exponent overflow.
=cut*/
-BIGNUM* BN_from_string(PINTD_ char* s2) {
+BIGNUM*
+BN_from_string(PINTD_ char* s2) {
BIGNUM *result;
BIGNUM *temp;
@@ -467,20 +484,25 @@
else if (!in_number) {
/* we've not yet seen any digits */
if (*s2 == '-') {
- if (seen_plus || negative || seen_dot)
- BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX, "Incorrect number format");
+ if (seen_plus || negative || seen_dot) {
+ BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX,
+ "Incorrect number format");
+ }
negative = 1;
}
else if (*s2 == '.') {
seen_dot = 1;
}
else if (*s2 == '+') {
- if (seen_plus || negative || seen_dot)
- BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX, "Incorrect number format");
+ if (seen_plus || negative || seen_dot) {
+ BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX,
+ "Incorrect number format");
+ }
seen_plus = 1; /* be very quiet */
}
else {
- BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX, "Incorrect number format");
+ BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX,
+ "Incorrect number format");
}
}
else {
@@ -500,11 +522,13 @@
exp_sign = -1;
}
else {
- BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX, "b Incorrect number format");
+ BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX,
+ "Incorrect number format");
}
}
else { /* We fall through here if we don't recognise something */
- BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX, "c Incorrect number format");
+ BN_EXCEPT(PINT_ BN_CONVERSION_SYNTAX,
+ "c Incorrect number format");
}
}
s2++; /* rinse, lather... */
@@ -558,7 +582,8 @@
Removes any zeros before the msd and after the lsd
=cut*/
-void BN_strip_lead_zeros(PINTD_ BIGNUM* bn) {
+void
+BN_strip_lead_zeros(PINTD_ BIGNUM* bn) {
INTVAL msd, i;
msd = bn->digits-1;
@@ -568,7 +593,6 @@
}
bn->digits -= bn->digits-1 - msd;
-
}
/*=item BN_strip_tail_zeros(BIGNUM *victim)
@@ -578,7 +602,8 @@
=cut*/
-void BN_strip_tail_zeros(PINTD_ BIGNUM *bn) {
+void
+BN_strip_tail_zeros(PINTD_ BIGNUM *bn) {
INTVAL lsd, i;
lsd = 0;
@@ -595,7 +620,8 @@
for (i=0; i< bn->digits -lsd; i++) {
BN_setd(bn, i, BN_getd(bn, i+lsd));
}
- CHECK_OVERFLOW( bn->expn, lsd, BN_EXPN_MAX, "overflow when striping zeros");
+ CHECK_OVERFLOW( bn->expn, lsd, BN_EXPN_MAX,
+ "overflow when striping zeros");
bn->expn += lsd;
bn->digits -= lsd;
}
@@ -606,7 +632,8 @@
is possible.
=cut*/
-void BN_make_integer(PINTD_ BIGNUM* bn, BN_CONTEXT* context) {
+void
+BN_make_integer(PINTD_ BIGNUM* bn, BN_CONTEXT* context) {
/* Normal bignum */
if (bn->expn > 0 && bn->digits + bn->expn <= context->precision) {
INTVAL i;
@@ -632,7 +659,8 @@
To check if a number is equal to zero, use BN_is_zero.
=cut*/
-void BN_really_zero(PINTD_ BIGNUM* bn) {
+void
+BN_really_zero(PINTD_ BIGNUM* bn) {
INTVAL i;
for (i=0; i< bn->digits; i++)
if (BN_getd(bn, i) != 0) return;
@@ -668,7 +696,8 @@
=cut*/
-int BN_round (PINTD_ BIGNUM *bn, BN_CONTEXT* context) {
+int
+BN_round (PINTD_ BIGNUM *bn, BN_CONTEXT* context) {
assert(bn!= NULL);
assert(context != NULL);
@@ -682,8 +711,10 @@
if (context->lost_digits) {
INTVAL digit;
for (digit = 0; digit < bn->digits - context->precision; digit++) {
- if (BN_getd(bn, digit) != 0)
- BN_EXCEPT(PINT_ BN_LOST_DIGITS, "information lost while rounding" );
+ if (BN_getd(bn, digit) != 0) {
+ BN_EXCEPT(PINT_ BN_LOST_DIGITS,
+ "digits lost while rounding" );
+ }
}
}
@@ -710,7 +741,9 @@
INTVAL i = bn->digits - context->precision -2;
if (i > -1) {
while (i>=0) {
- if (BN_getd(bn, i) != 0) return BN_round_up(PINT_ bn, context);
+ if (BN_getd(bn, i) != 0) {
+ return BN_round_up(PINT_ bn, context);
+ }
i--;
}
}
@@ -733,7 +766,8 @@
}
/* These are internal functions, don't call them with -ve precision */
-int BN_round_up(PINTD_ BIGNUM *bn, BN_CONTEXT* context) {
+int
+BN_round_up(PINTD_ BIGNUM *bn, BN_CONTEXT* context) {
INTVAL i, carry;
/* Do a cheap num += 1E+(num->expn) */
@@ -763,7 +797,8 @@
}
/* These are internal functions, don't call them with -ve precision */
-int BN_round_down(PINT_ BIGNUM *bn, BN_CONTEXT* context) {
+int
+BN_round_down(PINT_ BIGNUM *bn, BN_CONTEXT* context) {
INTVAL i =0;
INTVAL extra;
@@ -788,14 +823,17 @@
least I<precision>.
=cut*/
-void BN_round_as_integer(PINTD_ BIGNUM *bn, BN_CONTEXT *context) {
+void
+BN_round_as_integer(PINTD_ BIGNUM *bn, BN_CONTEXT *context) {
INTVAL i;
BN_CONTEXT temp_context;
if (bn->expn < context->precision) {
if (context->lost_digits) {
/* Are we losing information? */
- for (i=0; i< (context->precision - bn->expn) && i<bn->digits; i++) {
+ for (i=0;
+ i< (context->precision - bn->expn) && i<bn->digits;
+ i++) {
if (BN_getd(bn, i) != 0)
BN_EXCEPT(BN_LOST_DIGITS, "truncating IntVal");
}
@@ -872,7 +910,8 @@
=cut*/
void
-BN_arith_setup(PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT
*context, BN_SAVE_PREC* restore) {
+BN_arith_setup(PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context, BN_SAVE_PREC* restore) {
BN_strip_lead_zeros(PINT_ one);
BN_strip_lead_zeros(PINT_ two);
BN_round(PINT_ one, context);
@@ -890,8 +929,10 @@
=cut*/
void
-BN_arith_cleanup(PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT
*context, BN_SAVE_PREC* restore) {
+BN_arith_cleanup(PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context, BN_SAVE_PREC* restore) {
INTVAL i;
+ INTVAL lost_save;
if (restore && one->digits != restore->one.digits) {
if (one->expn < restore->one.expn) {
for (i=0; i<restore->one.digits; i++)
@@ -908,7 +949,11 @@
}
two->digits = restore->two.digits;
}
+ /* We don't raise lost_digits after an operation, only beforehand */
+ lost_save = context->lost_digits;
+ context->lost_digits = 0;
BN_round(PINT_ result, context);
+ context->lost_digits = lost_save;
BN_strip_lead_zeros(PINT_ result);
BN_really_zero(PINT_ result);
BN_make_integer(PINT_ result, context);
@@ -920,7 +965,8 @@
place.
=cut*/
-void BN_align(PINTD_ BIGNUM* one, BIGNUM* two) {
+void
+BN_align(PINTD_ BIGNUM* one, BIGNUM* two) {
INTVAL i;
INTVAL diff;
@@ -1015,7 +1061,9 @@
/* Actual addition code, assumes two positive operands and
an allocated result object and context */
-void BN_iadd (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT *context)
{
+void
+BN_iadd (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context) {
INTVAL i;
int carry, dig;
@@ -1058,7 +1106,8 @@
=cut*/
void
-BN_subtract(PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT *context) {
+BN_subtract(PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context) {
BN_SAVE_PREC restore;
BN_arith_setup(PINT_ result, one, two, context, &restore);
@@ -1081,7 +1130,8 @@
}
void
-BN_isubtract (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT *context)
{
+BN_isubtract (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context) {
INTVAL i;
int carry, dig;
/* Make sure we don't do work we don't need, or add precision where
@@ -1099,7 +1149,8 @@
BN_align(PINT_ one, two);
- /* as a-b == -(b-a), we find larger of a and b and make sure it is in one */
+ /* as a-b == -(b-a), we find larger of
+ a and b and make sure it is in one */
carry = 0;
for (i=one->digits -1; i>-1; i--) {
carry = BN_getd(one, i) - BN_getd(two, i);
@@ -1146,7 +1197,8 @@
Perform unary + on one. Does all the rounding and what have you.
=cut*/
-void BN_plus(PINTD_ BIGNUM* result, BIGNUM *one, BN_CONTEXT *context) {
+void
+BN_plus(PINTD_ BIGNUM* result, BIGNUM *one, BN_CONTEXT *context) {
BN_arith_setup(PINT_ result, one, one, context, NULL);
BN_copy(PINT_ result, one);
BN_arith_cleanup(PINT_ result, one, one, context, NULL);
@@ -1157,7 +1209,8 @@
Perform unary - on one. Does all the rounding and what have you.
=cut*/
-void BN_minus(PINTD_ BIGNUM* result, BIGNUM *one, BN_CONTEXT *context) {
+void
+BN_minus(PINTD_ BIGNUM* result, BIGNUM *one, BN_CONTEXT *context) {
BN_arith_setup(PINT_ result, one, one, context, NULL);
BN_copy(PINT_ result, one);
result->sign = result->sign ? 0 : 1;
@@ -1177,60 +1230,28 @@
=cut*/
void
-BN_compare (PINT_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT *context) {
- INTVAL i,j;
- int cmp;
+BN_compare (PINT_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context) {
+ INTVAL cmp;
BN_arith_setup(PINT_ result, one, two, context, NULL);
result->digits = 1;
result->expn = 0;
- if (one->sign != two->sign) {
- result->sign = one->sign;
- BN_setd(result, 0, 1);
- }
- else if (one->expn + one->digits > two->expn + two->digits) {
- result->sign = one->sign;
- BN_setd(result, 0, 1);
- }
- else if (one->expn + one->digits < two->expn + two->digits) {
- result->sign = one->sign ? 0:1;
- BN_setd(result, 0, 1);
- }
- else { /* Same sign, same "size" */
- for (i=0; i<one->digits && i<two->digits; i++) {
- cmp = BN_getd(one, one->digits-1-i) - BN_getd(two, two->digits-1-i);
- if (cmp) break;
- }
- if (!cmp) {
- if (i==one->digits) {
- for (i=i; i<two->digits; i++) {
- cmp = 0-BN_getd(two, two->digits-1-i);
- if (cmp) break;
- }
- }
- else if (i==two->digits) {
- for (i=i; i<one->digits; i++) {
- cmp = BN_getd(one, one->digits-1-i);
- if (cmp) break;
- }
- }
- }
- /* now check the value of cmp */
- if (cmp > 0) {
- result->sign = one->sign;
- BN_setd(result, 0, 1);
+ cmp = BN_comp(PINT_ one, two);
+
+ if (cmp == 0) {
+ BN_setd(result, 0, 0);
+ result->sign = 0;
}
- else if (cmp < 0) {
- result->sign = one->sign ? 0 : 1;
+ else if (cmp > 0) {
BN_setd(result, 0, 1);
- }
- else {
result->sign = 0;
- BN_setd(result,0,0);
}
+ else {
+ BN_setd(result, 0, 1);
+ result->sign = 1;
}
-
BN_arith_cleanup(PINT_ result, one, two, context, NULL);
}
@@ -1240,7 +1261,8 @@
=cut*/
void
-BN_multiply (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT *context) {
+BN_multiply (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context) {
INTVAL i,j;
int carry, dig;
@@ -1281,8 +1303,10 @@
}
i = one->expn + two->expn;
- CHECK_OVERFLOW(result->expn, i, BN_EXPN_MAX, "overflow in multiplication");
- CHECK_UNDERFLOW(result->expn,-i, BN_EXPN_MIN, "underflow in multipliaction");
+ CHECK_OVERFLOW(result->expn, i, BN_EXPN_MAX,
+ "overflow in multiplication");
+ CHECK_UNDERFLOW(result->expn,-i, BN_EXPN_MIN,
+ "underflow in multipliaction");
result->expn = i;
result->sign = 1 & (one->sign ^ two->sign);
@@ -1305,7 +1329,9 @@
=cut*/
-void BN_divide(PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT
*context) {
+void
+BN_divide(PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context) {
BIGNUM* rem = BN_new(PINT_ 1);
BN_arith_setup(PINT_ result, one, two, context, NULL);
BN_idivide(PINT_ result, one, two, context, BN_DIV_DIVIDE, rem);
@@ -1318,9 +1344,6 @@
/*XXX: write this rounding to cope with precision < 1 */
if (context->rounding == ROUND_HALF_EVEN) {
if (result->digits > context->precision) {
- if (context->lost_digits) {
- BN_EXCEPT(PINT_ BN_LOST_DIGITS, "digits lost after division");
- }
/* We collected precision + 1 digits... */
BN_really_zero(PINT_ rem);
if (BN_getd(result, 0) > 5) {
@@ -1351,7 +1374,12 @@
}
else { /* Other roundings just need digits to play with */
+ INTVAL save_lost;
+ /* We don't warn on lost digits here, as is after an operation */
+ save_lost = context->lost_digits;
+ context->lost_digits = 0;
BN_round(PINT_ result, context);
+ context->lost_digits = save_lost;
}
BN_really_zero(PINT_ result);
@@ -1384,7 +1412,8 @@
=cut*/
void
-BN_divide_integer (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT
*context) {
+BN_divide_integer (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context) {
BIGNUM* rem = BN_new(PINT_ 1);
BN_arith_setup(PINT_ result, one, two, context, NULL);
BN_idivide(PINT_ result, one, two, context, BN_DIV_DIVINT, rem);
@@ -1401,7 +1430,8 @@
INTVAL i;
BN_grow(PINT_ result, result->expn + result->digits);
for (i=0; i<result->digits; i++) {
- BN_setd(result, result->expn + result->digits -1 -i, BN_getd(result, i));
+ BN_setd(result, result->expn + result->digits -1 -i,
+ BN_getd(result, i));
}
for (i=0; i<result->expn; i++) {
BN_setd(result, i ,0);
@@ -1420,7 +1450,8 @@
=cut*/
void
-BN_remainder (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two, BN_CONTEXT *context)
{
+BN_remainder (PINTD_ BIGNUM* result, BIGNUM *one, BIGNUM *two,
+ BN_CONTEXT *context) {
BIGNUM* fake;
if (BN_is_zero(PINT_ one)) {
@@ -1532,7 +1563,7 @@
/* We collect one more digit than precision requires, then
round in divide, if we're doing divint or rem then we terminate
at the decimal point and return */
- if (context->precison > 0) {
+ if (context->precision > 0) {
if (t2->digits == context->precision + 1) break;
}
else {
@@ -1572,7 +1603,8 @@
}
/* Comparison with no rounding etc. */
-INTVAL BN_comp (PINTD_ BIGNUM *one, BIGNUM *two) {
+INTVAL
+BN_comp (PINTD_ BIGNUM *one, BIGNUM *two) {
INTVAL i,j;
int cmp;
@@ -1580,7 +1612,7 @@
BN_strip_lead_zeros(PINT_ two);
if (one->sign != two->sign) {
- return one->sign ? 1 : -1;
+ return one->sign ? -1 : 1;
}
else if (one->expn + one->digits > two->expn + two->digits) {
return one->sign ? -1 : 1;
@@ -1590,23 +1622,24 @@
}
else { /* Same sign, same "size" */
for (i=0; i<one->digits && i<two->digits; i++) {
- cmp = BN_getd(one, one->digits-1-i) - BN_getd(two, two->digits-1-i);
- if (cmp) return cmp;
+ cmp = BN_getd(one, one->digits-1-i)
+ - BN_getd(two, two->digits-1-i);
+ if (cmp) return one->sign ? -cmp : cmp;
}
if (!cmp) {
if (i==one->digits) {
for (i=i; i<two->digits; i++) {
cmp = 0-BN_getd(two, two->digits-1-i);
- if (cmp) return cmp;
+ if (cmp) return one->sign ? -cmp : cmp;
}
}
else if (i==two->digits) {
for (i=i; i<one->digits; i++) {
cmp = BN_getd(one, one->digits-1-i);
- if (cmp) return cmp;
+ if (cmp) return one->sign ? -cmp : cmp;
}
}
- return cmp;
+ return one->sign ? -cmp : cmp;
}
}
}
@@ -1618,7 +1651,8 @@
XXX To Do
=cut*/
-void BN_power(PINTD_ BIGNUM* result, BIGNUM* bignum,
+void
+BN_power(PINTD_ BIGNUM* result, BIGNUM* bignum,
BIGNUM* expn, BN_CONTEXT* context) {
BN_arith_setup(PINT_ result, bignum, expn, context, NULL);
@@ -1634,7 +1668,9 @@
XXX To Do
=cut*/
-void BN_rescale(PINTD_ BIGNUM* result, BIGNUM* one, BIGNUM* two, BN_CONTEXT*
context) {
+void
+BN_rescale(PINTD_ BIGNUM* result, BIGNUM* one, BIGNUM* two,
+ BN_CONTEXT* context) {
INTVAL expn;
INTVAL lost = context->lost_digits;
@@ -1653,7 +1689,8 @@
representation cannot be created.
=cut*/
-INTVAL BN_to_int(PINT_ BIGNUM* bn, BN_CONTEXT* context) {
+INTVAL
+BN_to_int(PINT_ BIGNUM* bn, BN_CONTEXT* context) {
INTVAL insig, i;
INTVAL result = 0;
INTVAL maxdigs = BN_D_PER_INT < context->precision ?
@@ -1698,7 +1735,8 @@
return bn->sign ? -result : result;
}
-INTVAL BN_is_zero(BIGNUM* foo) {
+INTVAL
+BN_is_zero(BIGNUM* foo) {
BN_really_zero(foo);
if (foo->digits == 1 && foo->expn == 0 && BN_getd(foo, 0) == 0) {
return 1;
1.4 +4 -4 parrot/types/bignum.h
Index: bignum.h
===================================================================
RCS file: /home/perlcvs/parrot/types/bignum.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- bignum.h 21 Feb 2002 16:38:47 -0000 1.3
+++ bignum.h 21 Feb 2002 21:12:28 -0000 1.4
@@ -1,6 +1,6 @@
/* bignum.h -- Infinite precision bcd for parrot -- Alex Gough, 2002 */
-/* $Id: bignum.h,v 1.3 2002/02/21 16:38:47 ajgough Exp $ */
+/* $Id: bignum.h,v 1.4 2002/02/21 21:12:28 ajgough Exp $ */
/* Some of this file will want to be moved to the parrot include
directories, but some should stay here, for the sake of being easily
@@ -46,14 +46,14 @@
nibs == 3, digits == 14
*/
-struct parrot_bignum_t {
+typedef struct {
BN_NIB* buffer; /* string of nibbles */
UINTVAL nibs; /* nibs allocated, in sizeof(BN_NIB) */
- UNITVAL flags; /* May store, say +Inf */
+ UINTVAL flags; /* May store, say +Inf */
INTVAL digits; /* digits used */
int sign; /* sign of number, 0=> positive or zero, 1 => negative */
INTVAL expn; /* exponent of number */
-};
+} parrot_bignum_t;
#define BIGNUM parrot_bignum_t