VM: fix bignum>fixnum-strict conversion, previously most-negative-fixnum
>bignum bignum>fixnum-strict didn't workdb4
parent
95fa3eba19
commit
ed702209ce
|
@ -1,4 +1,4 @@
|
||||||
USING: kernel math namespaces make tools.test ;
|
USING: kernel layouts math math.private namespaces make tools.test ;
|
||||||
IN: math.tests
|
IN: math.tests
|
||||||
|
|
||||||
[ ] [ 5 [ ] times ] unit-test
|
[ ] [ 5 [ ] times ] unit-test
|
||||||
|
@ -96,3 +96,5 @@ IN: math.tests
|
||||||
|
|
||||||
{ t } [ 128 2^ sq 256 2^ = ] unit-test
|
{ t } [ 128 2^ sq 256 2^ = ] unit-test
|
||||||
{ t } [ 128 2^ neg sq 256 2^ = ] unit-test
|
{ t } [ 128 2^ neg sq 256 2^ = ] unit-test
|
||||||
|
|
||||||
|
{ t } [ most-negative-fixnum dup >bignum bignum>fixnum-strict = ] unit-test
|
||||||
|
|
|
@ -388,11 +388,27 @@ BIGNUM_TO_FOO(fixnum, fixnum, fixnum, cell)
|
||||||
BIGNUM_TO_FOO(long_long, int64_t, int64_t, uint64_t)
|
BIGNUM_TO_FOO(long_long, int64_t, int64_t, uint64_t)
|
||||||
BIGNUM_TO_FOO(ulong_long, uint64_t, int64_t, uint64_t)
|
BIGNUM_TO_FOO(ulong_long, uint64_t, int64_t, uint64_t)
|
||||||
|
|
||||||
|
bool bignum_fits_fixnum_p(bignum* bn) {
|
||||||
|
fixnum len = BIGNUM_LENGTH(bn);
|
||||||
|
if (len == 0)
|
||||||
|
return true;
|
||||||
|
if (len > 1)
|
||||||
|
return false;
|
||||||
|
bignum_digit_type dig = BIGNUM_START_PTR(bn)[0];
|
||||||
|
return (BIGNUM_NEGATIVE_P(bn) && dig <= -fixnum_min) ||
|
||||||
|
(!BIGNUM_NEGATIVE_P(bn) && dig <= fixnum_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell bignum_maybe_to_fixnum(bignum* bn) {
|
||||||
|
if (bignum_fits_fixnum_p(bn))
|
||||||
|
return tag_fixnum(bignum_to_fixnum(bn));
|
||||||
|
return tag<bignum>(bn);
|
||||||
|
}
|
||||||
|
|
||||||
/* cannot allocate memory */
|
/* cannot allocate memory */
|
||||||
fixnum factor_vm::bignum_to_fixnum_strict(bignum* bn) {
|
fixnum factor_vm::bignum_to_fixnum_strict(bignum* bn) {
|
||||||
fixnum len = BIGNUM_LENGTH(bn);
|
|
||||||
bignum_digit_type *digits = BIGNUM_START_PTR(bn);
|
if (!bignum_fits_fixnum_p(bn)) {
|
||||||
if ((len == 1 && digits[0] > fixnum_max) || (len > 1)) {
|
|
||||||
general_error(ERROR_OUT_OF_FIXNUM_RANGE, tag<bignum>(bn), false_object);
|
general_error(ERROR_OUT_OF_FIXNUM_RANGE, tag<bignum>(bn), false_object);
|
||||||
}
|
}
|
||||||
fixnum fix = bignum_to_fixnum(bn);
|
fixnum fix = bignum_to_fixnum(bn);
|
||||||
|
|
|
@ -42,6 +42,7 @@ enum bignum_comparison {
|
||||||
bignum_comparison_greater = 1
|
bignum_comparison_greater = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cell bignum_maybe_to_fixnum(bignum* bn);
|
||||||
cell bignum_to_cell(bignum* bn);
|
cell bignum_to_cell(bignum* bn);
|
||||||
fixnum bignum_to_fixnum(bignum* bn);
|
fixnum bignum_to_fixnum(bignum* bn);
|
||||||
int64_t bignum_to_long_long(bignum* bn);
|
int64_t bignum_to_long_long(bignum* bn);
|
||||||
|
|
11
vm/math.cpp
11
vm/math.cpp
|
@ -2,17 +2,6 @@
|
||||||
|
|
||||||
namespace factor {
|
namespace factor {
|
||||||
|
|
||||||
cell bignum_maybe_to_fixnum(bignum* bn) {
|
|
||||||
if (BIGNUM_ZERO_P(bn))
|
|
||||||
return tag_fixnum(0);
|
|
||||||
fixnum len = BIGNUM_LENGTH(bn);
|
|
||||||
bignum_digit_type *digits = BIGNUM_START_PTR(bn);
|
|
||||||
if (len == 1 && digits[0] >= fixnum_min && digits[0] <= fixnum_max) {
|
|
||||||
return tag_fixnum(bignum_to_fixnum(bn));
|
|
||||||
}
|
|
||||||
return tag<bignum>(bn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void factor_vm::primitive_bignum_to_fixnum() {
|
void factor_vm::primitive_bignum_to_fixnum() {
|
||||||
ctx->replace(tag_fixnum(bignum_to_fixnum(untag<bignum>(ctx->peek()))));
|
ctx->replace(tag_fixnum(bignum_to_fixnum(untag<bignum>(ctx->peek()))));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue