mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-18 21:29:18 +02:00
Issue #519 - Properly handle doubles in remainder
This commit is contained in:
parent
034d26a18a
commit
749d4b6a0c
2 changed files with 21 additions and 11 deletions
24
runtime.c
24
runtime.c
|
@ -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)){
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
|
|
@ -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))
|
||||
|
@ -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))))
|
||||
)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue