Skip to content

Commit

Permalink
Issue #519 - Properly handle doubles in remainder
Browse files Browse the repository at this point in the history
  • Loading branch information
justinethier committed Jan 8, 2024
1 parent 034d26a commit 749d4b6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
24 changes: 18 additions & 6 deletions runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -4629,6 +4629,7 @@ void Cyc_bignum_remainder(void *data, object cont, object num1, object num2, obj
void Cyc_remainder(void *data, object cont, object num1, object num2)
{
int i = 0, j = 0;
double ii = 0, jj = 0;
object result;
if (obj_is_int(num1)) {
if (obj_is_int(num2)){
Expand All @@ -4641,8 +4642,9 @@ void Cyc_remainder(void *data, object cont, object num1, object num2)
Cyc_bignum_remainder(data, cont, bn, num2, bn);
}
else if (is_object_type(num2) && type_of(num2) == double_tag){
i = obj_obj2int(num1);
j = ((double_type *)num2)->value;
ii = obj_obj2int(num1);
jj = ((double_type *)num2)->value;
goto handledouble;
}
else {
goto typeerror;
Expand All @@ -4658,6 +4660,7 @@ void Cyc_remainder(void *data, object cont, object num1, object num2)
Cyc_bignum_remainder(data, cont, num1, num2, rem);
}
else if (is_object_type(num2) && type_of(num2) == double_tag){
// TODO: correct to convert bignum to double here
j = ((double_type *)num2)->value;
alloc_bignum(data, bn);
Cyc_int2bignum(obj_obj2int(j), &(bn->bn));
Expand All @@ -4668,18 +4671,21 @@ void Cyc_remainder(void *data, object cont, object num1, object num2)
}
} else if (is_object_type(num1) && type_of(num1) == double_tag){
if (obj_is_int(num2)){
i = ((double_type *)num1)->value;
j = obj_obj2int(num2);
ii = ((double_type *)num1)->value;
jj = obj_obj2int(num2);
goto handledouble;
}
else if (is_object_type(num2) && type_of(num2) == bignum_tag){
// TODO: convert bignum to double here
i = ((double_type *)num1)->value;
alloc_bignum(data, bn);
Cyc_int2bignum(obj_obj2int(i), &(bn->bn));
Cyc_bignum_remainder(data, cont, bn, num2, bn);
}
else if (is_object_type(num2) && type_of(num2) == double_tag){
i = ((double_type *)num1)->value;
j = ((double_type *)num2)->value;
ii = ((double_type *)num1)->value;
jj = ((double_type *)num2)->value;
goto handledouble;
}
else {
goto typeerror;
Expand All @@ -4690,6 +4696,12 @@ void Cyc_remainder(void *data, object cont, object num1, object num2)
if (j == 0) { Cyc_rt_raise_msg(data, "Divide by zero"); }
result = obj_int2obj(i % j);
return_closcall1(data, cont, result);
handledouble:
{
if (jj == 0) { Cyc_rt_raise_msg(data, "Divide by zero"); }
make_double(dresult, fmod(ii, jj));
return_closcall1(data, cont, &dresult);
}
typeerror:
{
make_string(s, "Bad argument type");
Expand Down
8 changes: 3 additions & 5 deletions tests/base.scm
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@
(test (values -2 -1) (truncate/ -5 2))
(test (values -2 1) (truncate/ 5 -2))
(test (values 2 -1) (truncate/ -5 -2))
; TODO:
; (test (values 2.0 -1.0) (truncate/ -5.0 -2))
(test (values 2.0 -1.0) (truncate/ -5.0 -2))

(test 4 (gcd 32 -36))
(test 0 (gcd))
Expand All @@ -95,9 +94,8 @@
(test 4.0 (round 7/2)) ;; Rationals not supported, so result is inexact
(test 7 (round 7))

; TODO:
;(test 3 (numerator (/ 6 4)))
;(test 2 (denominator (/ 6 4)))
(test 3.0 (numerator (/ 6 4))) ;; Inexact because we don't support rationals yet
(test 2.0 (denominator (/ 6 4))) ;; Inexact because we don't support rationals yet
(test 2.0 (denominator (inexact (/ 6 4))))
)

Expand Down

0 comments on commit 749d4b6

Please sign in to comment.