mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-20 22:29:16 +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)
|
void Cyc_remainder(void *data, object cont, object num1, object num2)
|
||||||
{
|
{
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
|
double ii = 0, jj = 0;
|
||||||
object result;
|
object result;
|
||||||
if (obj_is_int(num1)) {
|
if (obj_is_int(num1)) {
|
||||||
if (obj_is_int(num2)){
|
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);
|
Cyc_bignum_remainder(data, cont, bn, num2, bn);
|
||||||
}
|
}
|
||||||
else if (is_object_type(num2) && type_of(num2) == double_tag){
|
else if (is_object_type(num2) && type_of(num2) == double_tag){
|
||||||
i = obj_obj2int(num1);
|
ii = obj_obj2int(num1);
|
||||||
j = ((double_type *)num2)->value;
|
jj = ((double_type *)num2)->value;
|
||||||
|
goto handledouble;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
goto typeerror;
|
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);
|
Cyc_bignum_remainder(data, cont, num1, num2, rem);
|
||||||
}
|
}
|
||||||
else if (is_object_type(num2) && type_of(num2) == double_tag){
|
else if (is_object_type(num2) && type_of(num2) == double_tag){
|
||||||
|
// TODO: correct to convert bignum to double here
|
||||||
j = ((double_type *)num2)->value;
|
j = ((double_type *)num2)->value;
|
||||||
alloc_bignum(data, bn);
|
alloc_bignum(data, bn);
|
||||||
Cyc_int2bignum(obj_obj2int(j), &(bn->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){
|
} else if (is_object_type(num1) && type_of(num1) == double_tag){
|
||||||
if (obj_is_int(num2)){
|
if (obj_is_int(num2)){
|
||||||
i = ((double_type *)num1)->value;
|
ii = ((double_type *)num1)->value;
|
||||||
j = obj_obj2int(num2);
|
jj = obj_obj2int(num2);
|
||||||
|
goto handledouble;
|
||||||
}
|
}
|
||||||
else if (is_object_type(num2) && type_of(num2) == bignum_tag){
|
else if (is_object_type(num2) && type_of(num2) == bignum_tag){
|
||||||
|
// TODO: convert bignum to double here
|
||||||
i = ((double_type *)num1)->value;
|
i = ((double_type *)num1)->value;
|
||||||
alloc_bignum(data, bn);
|
alloc_bignum(data, bn);
|
||||||
Cyc_int2bignum(obj_obj2int(i), &(bn->bn));
|
Cyc_int2bignum(obj_obj2int(i), &(bn->bn));
|
||||||
Cyc_bignum_remainder(data, cont, bn, num2, bn);
|
Cyc_bignum_remainder(data, cont, bn, num2, bn);
|
||||||
}
|
}
|
||||||
else if (is_object_type(num2) && type_of(num2) == double_tag){
|
else if (is_object_type(num2) && type_of(num2) == double_tag){
|
||||||
i = ((double_type *)num1)->value;
|
ii = ((double_type *)num1)->value;
|
||||||
j = ((double_type *)num2)->value;
|
jj = ((double_type *)num2)->value;
|
||||||
|
goto handledouble;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
goto typeerror;
|
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"); }
|
if (j == 0) { Cyc_rt_raise_msg(data, "Divide by zero"); }
|
||||||
result = obj_int2obj(i % j);
|
result = obj_int2obj(i % j);
|
||||||
return_closcall1(data, cont, result);
|
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:
|
typeerror:
|
||||||
{
|
{
|
||||||
make_string(s, "Bad argument type");
|
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))
|
(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 4 (gcd 32 -36))
|
||||||
(test 0 (gcd))
|
(test 0 (gcd))
|
||||||
|
@ -95,9 +94,8 @@
|
||||||
(test 4.0 (round 7/2)) ;; Rationals not supported, so result is inexact
|
(test 4.0 (round 7/2)) ;; Rationals not supported, so result is inexact
|
||||||
(test 7 (round 7))
|
(test 7 (round 7))
|
||||||
|
|
||||||
; TODO:
|
(test 3.0 (numerator (/ 6 4))) ;; Inexact because we don't support rationals yet
|
||||||
;(test 3 (numerator (/ 6 4)))
|
(test 2.0 (denominator (/ 6 4))) ;; Inexact because we don't support rationals yet
|
||||||
;(test 2 (denominator (/ 6 4)))
|
|
||||||
(test 2.0 (denominator (inexact (/ 6 4))))
|
(test 2.0 (denominator (inexact (/ 6 4))))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue