Skip to content

Commit

Permalink
Issue #510 - Exact conversion of large doubles
Browse files Browse the repository at this point in the history
Allow `exact` to convert large double values to bignums.
  • Loading branch information
justinethier committed Sep 12, 2023
1 parent f8fbb9a commit e8ba3f1
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
25 changes: 19 additions & 6 deletions include/cyclone/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ int Cyc_have_mstreams();
} else if (type_of(z) == bignum_tag) { \
return_closcall1(data, cont, z); \
} else if (type_of(z) == complex_num_tag) { \
return_closcall1(data, cont, z); \
} else { \
double d = ((double_type *)z)->value; \
if (isnan(d)) { \
Expand All @@ -525,15 +526,15 @@ int Cyc_have_mstreams();
Cyc_rt_raise2(data, "Expected number but received", z); \
} else if (d == -INFINITY) { \
Cyc_rt_raise2(data, "Expected number but received", z); \
} else if (d > CYC_FIXNUM_MAX || d < CYC_FIXNUM_MIN){ \
alloc_bignum(data, bn); \
BIGNUM_CALL(mp_set_double(&bignum_value(bn), d)); \
return_closcall1(data, cont, bn); \
} \
i = (int)OP(((double_type *)z)->value); \
} \
return_closcall1(data, cont, obj_int2obj(i))

// TODO: truncate complex number components
// TODO: what if double is outside fixnum range??
// need to convert to a bignum

/**
* Directly compute exact
*/
Expand All @@ -546,13 +547,25 @@ int Cyc_have_mstreams();
i = (int)OP(((integer_type *)z)->value); \
} else if (type_of(z) == bignum_tag) { \
return z; \
} else if (type_of(z) == complex_num_tag) { \
return z; \
} else { \
double d = ((double_type *)z)->value; \
if (isnan(d)) { \
Cyc_rt_raise2(data, "Expected number but received", z); \
} else if (d == INFINITY) { \
Cyc_rt_raise2(data, "Expected number but received", z); \
} else if (d == -INFINITY) { \
Cyc_rt_raise2(data, "Expected number but received", z); \
} else if (d > CYC_FIXNUM_MAX || d < CYC_FIXNUM_MIN){ \
alloc_bignum(data, bn); \
BIGNUM_CALL(mp_set_double(&bignum_value(bn), d)); \
return bn; \
} \
i = (int)OP(((double_type *)z)->value); \
} \
return obj_int2obj(i);

// TODO: sync changes from above CPS macro

/**
* Take Scheme object that is a number and return the number as a C type
*/
Expand Down
2 changes: 2 additions & 0 deletions tests/base.scm
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
(test -1 (exact -1.0))
(test -1 (exact -1.1))
(test -1 (exact -1.1))
(test #t (bignum? (exact 111111111111111111111111111.0)))
(test #t (bignum? (exact -111111111111111111111111111.0)))
;(test +inf.0 (exact +inf.0))
)

Expand Down

0 comments on commit e8ba3f1

Please sign in to comment.