Skip to content

Commit

Permalink
Use new functions introduced in ltm v1.2.0...
Browse files Browse the repository at this point in the history
to instead of our own implementations written before they were available
upstream.
  • Loading branch information
MasterDuke17 committed Feb 9, 2020
1 parent 0dd1364 commit 056c523
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 163 deletions.
18 changes: 4 additions & 14 deletions src/6model/reprs/P6bigint.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,8 @@ static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *d
void MVM_p6bigint_store_as_mp_int(MVMThreadContext *tc, MVMP6bigintBody *body, MVMint64 value) {
mp_err err;
mp_int *i = MVM_malloc(sizeof(mp_int));
if ((err = mp_init(i)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error creating a big integer from a native integer: %s", mp_error_to_string(err));
}
if (value >= 0) {
MVM_bigint_mp_set_uint64(i, (MVMuint64)value);
}
else {
MVM_bigint_mp_set_uint64(i, (MVMuint64)-value);
if ((err = mp_neg(i, i)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error negating a big integer: %s", mp_error_to_string(err));
}
if ((err = mp_init_i64(i, value)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error creating a big integer from a native integer (%"PRIi64"): %s", value, mp_error_to_string(err));
}
body->u.bigint = i;
}
Expand Down Expand Up @@ -137,10 +128,9 @@ static void set_uint(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void
else {
mp_err err;
mp_int *i = MVM_malloc(sizeof(mp_int));
if ((err = mp_init(i)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error setting a big integer from a native integer: %s", mp_error_to_string(err));
if ((err = mp_init_u64(i, value)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error creating a big integer from a native integer (%"PRIu64"): %s", value, mp_error_to_string(err));
}
MVM_bigint_mp_set_uint64(i, value);
body->u.bigint = i;
}
}
Expand Down
158 changes: 11 additions & 147 deletions src/math/bigintops.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,6 @@ MVM_STATIC_INLINE void adjust_nursery(MVMThreadContext *tc, MVMP6bigintBody *bod
}
}

/* Taken from mp_set_long, but portably accepts a 64-bit number. */
int MVM_bigint_mp_set_uint64(mp_int * a, MVMuint64 b) {
size_t x;
int res;

mp_zero (a);

/* set four bits at a time */
for (x = 0; x < sizeof(MVMuint64) * 2; x++) {
/* shift the number up four bits */
if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
return res;
}

/* OR in the top four bits of the source */
a->dp[0] |= (b >> ((sizeof(MVMuint64)) * 8 - 4)) & 15;

/* shift the source up to the next four bits */
b <<= 4;

/* ensure that digits are not clamped off */
a->used += 1;
}
mp_clamp(a);
return MP_OKAY;
}

/*
* Convert to double, assumes IEEE-754 conforming double. Taken from
* https://github.com/czurnieden/libtommath/blob/master/bn_mp_get_double.c
Expand Down Expand Up @@ -97,71 +70,6 @@ static MVMnum64 MVM_mp_get_double_shift(mp_int *a, int shift) {
return d;
}

static void from_num(MVMThreadContext *tc, MVMnum64 d, mp_int *a) {
mp_err err;
MVMnum64 d_digit = pow(2, MP_DIGIT_BIT);
MVMnum64 da = fabs(d);
MVMnum64 upper;
MVMnum64 lower;
MVMnum64 lowest;
MVMnum64 rest;
int digits = 0;

mp_zero(a);

while (da > d_digit * d_digit * d_digit) {;
da /= d_digit;
digits++;
}
if ((err = mp_grow(a, digits + 3)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error growing a big integer: %s", mp_error_to_string(err));
}

/* populate the top 3 digits */
upper = da / (d_digit*d_digit);
rest = fmod(da, d_digit*d_digit);
lower = rest / d_digit;
lowest = fmod(rest,d_digit );
if (upper >= 1) {
if ((err = MVM_bigint_mp_set_uint64(a, (MVMuint64) upper)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error setting a big integer to a uint64: %s", mp_error_to_string(err));
}
if ((err = mp_mul_2d(a, MP_DIGIT_BIT, a)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error in mp_mul_2d: %s", mp_error_to_string(err));
}
a->dp[0] = (mp_digit) lower;
if ((err = mp_mul_2d(a, MP_DIGIT_BIT, a)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error in mp_mul_2d: %s", mp_error_to_string(err));
}
} else {
if (lower >= 1) {
if ((err = MVM_bigint_mp_set_uint64(a, (MVMuint64) lower)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error setting a big integer to a uint64: %s", mp_error_to_string(err));
}
if ((err = mp_mul_2d(a, MP_DIGIT_BIT, a)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error in mp_mul_2d: %s", mp_error_to_string(err));
}
a->used = 2;
} else {
a->used = 1;
}
}
a->dp[0] = (mp_digit) lowest;

/* shift the rest */
if ((err = mp_mul_2d(a, MP_DIGIT_BIT * digits, a)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error in mp_mul_2d: %s", mp_error_to_string(err));
}
if (d < 0)
if ((err = mp_neg(a, a)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error negating a big integer: %s", mp_error_to_string(err));
}
mp_clamp(a);
if ((err = mp_shrink(a)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error shrinking a big integer: %s", mp_error_to_string(err));
}
}

/* Returns the body of a P6bigint, containing the bigint/smallint union, for
* operations that want to explicitly handle the two. */
static MVMP6bigintBody * get_bigint_body(MVMThreadContext *tc, MVMObject *obj) {
Expand All @@ -188,35 +96,13 @@ static mp_int * force_bigint(MVMThreadContext *tc, const MVMP6bigintBody *body,
}
else {
if (sizeof(mp_digit) > 4) {
MVMint64 value = body->u.smallint.value;
mp_int *i = tc->temp_bigints[idx];
if (value >= 0) {
mp_digit d = value;
mp_set(i, d);
}
else {
mp_digit d = -value;
mp_set(i, d);
mp_err err;
if ((err = mp_neg(i, i)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error negating a big integer: %s", mp_error_to_string(err));
}
}
mp_set_i64(i, body->u.smallint.value);
return i;
}
else {
MVMint32 value = body->u.smallint.value;
mp_int *i = tc->temp_bigints[idx];
if (value >= 0) {
mp_set_i32(i, value);
}
else {
mp_set_i32(i, -value);
mp_err err;
if ((err = mp_neg(i, i)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error negating a big integer: %s", mp_error_to_string(err));
}
}
mp_set_i32(i, body->u.smallint.value);
return i;
}
}
Expand All @@ -232,21 +118,8 @@ static void store_int64_result(MVMThreadContext *tc, MVMP6bigintBody *body, MVMi
else {
mp_err err;
mp_int *i = MVM_malloc(sizeof(mp_int));
if ((err = mp_init(i)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error creating a big integer: %s", mp_error_to_string(err));
}
if (result >= 0) {
if ((err = MVM_bigint_mp_set_uint64(i, (MVMuint64)result)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error setting a big integer to a uint64: %s", mp_error_to_string(err));
}
}
else {
if ((err = MVM_bigint_mp_set_uint64(i, (MVMuint64)-result)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error setting a big integer to a uint64: %s", mp_error_to_string(err));
}
if ((err = mp_neg(i, i)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error negating a big integer: %s", mp_error_to_string(err));
}
if ((err = mp_init_i64(i, result)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error creating a big integer from a native integer (%"PRIi64"): %s", result, mp_error_to_string(err));
}
body->u.bigint = i;
}
Expand Down Expand Up @@ -802,8 +675,8 @@ MVMObject * MVM_bigint_pow(MVMThreadContext *tc, MVMObject *a, MVMObject *b,
}
}
else {
MVMnum64 f_base = MVM_mp_get_double_shift(base, 0);
MVMnum64 f_exp = MVM_mp_get_double_shift(exponent, 0);
MVMnum64 f_base = mp_get_double(base);
MVMnum64 f_exp = mp_get_double(exponent);
r = MVM_repr_box_num(tc, num_type, pow(f_base, f_exp));
}
return r;
Expand Down Expand Up @@ -1165,20 +1038,10 @@ MVMString * MVM_bigint_to_str(MVMThreadContext *tc, MVMObject *a, int base) {
char *buf;
MVMString *result;

MVMint64 value = body->u.smallint.value;
if ((err = mp_init(&i)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error creating a big integer: %s", mp_error_to_string(err));
}
if (value >= 0) {
mp_set_ul(&i, value);
}
else {
mp_set_ul(&i, -value);
if ((err = mp_neg(&i, &i)) != MP_OKAY) {
mp_clear(&i);
MVM_exception_throw_adhoc(tc, "Error negating a big integer: %s", mp_error_to_string(err));
}
}
mp_set_i64(&i, body->u.smallint.value);

if ((err = mp_radix_size(&i, base, &len)) != MP_OKAY) {
mp_clear(&i);
Expand Down Expand Up @@ -1208,8 +1071,7 @@ MVMnum64 MVM_bigint_to_num(MVMThreadContext *tc, MVMObject *a) {
MVMP6bigintBody *ba = get_bigint_body(tc, a);

if (MVM_BIGINT_IS_BIG(ba)) {
mp_int *ia = ba->u.bigint;
return MVM_mp_get_double_shift(ia, 0);
return mp_get_double(ba->u.bigint);
} else {
return (double)ba->u.smallint.value;
}
Expand All @@ -1223,7 +1085,9 @@ MVMObject *MVM_bigint_from_num(MVMThreadContext *tc, MVMObject *result_type, MVM
if ((err = mp_init(ia)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error creating a big integer: %s", mp_error_to_string(err));
}
from_num(tc, n, ia);
if ((err = mp_set_double(ia, n)) != MP_OKAY) {
MVM_exception_throw_adhoc(tc, "Error storing an MVMnum64 (%f) in a big integer: %s", n, mp_error_to_string(err));
}
store_bigint_result(ba, ia);
return result;
}
Expand Down
2 changes: 0 additions & 2 deletions src/math/bigintops.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
int MVM_bigint_mp_set_uint64(mp_int * a, MVMuint64 b);

MVMObject * MVM_bigint_abs(MVMThreadContext *tc, MVMObject *result_type, MVMObject *a);
MVMObject * MVM_bigint_neg(MVMThreadContext *tc, MVMObject *result_type, MVMObject *a);
MVMObject * MVM_bigint_not(MVMThreadContext *tc, MVMObject *result_type, MVMObject *a);
Expand Down

0 comments on commit 056c523

Please sign in to comment.