Issue #55 - More arithmetic op support for complex

This commit is contained in:
Justin Ethier 2018-05-11 15:40:20 -04:00
parent f203e75b83
commit 89db7cca24
2 changed files with 107 additions and 0 deletions

View file

@ -695,6 +695,13 @@ typedef struct {
n.tag = complex_num_tag; \
n.value = (r + (i * I));
/** Assign given complex value to the given complex number object pointer */
#define assign_complex_num(pobj,v) \
((complex_num_type *)pobj)->hdr.mark = gc_color_red; \
((complex_num_type *)pobj)->hdr.grayed = 0; \
((complex_num_type *)pobj)->tag = complex_num_tag; \
complex_num_value(pobj) = v;
/**
* @brief Double-precision floating point type, also known as a flonum.
*/

100
runtime.c
View file

@ -3168,6 +3168,9 @@ object Cyc_fast_sum(void *data, object ptr, object x, object y) {
mp_add(&bnx, &bignum_value(y), &bignum_value(bn));
mp_clear(&bnx);
return bn;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, ((obj_obj2int(x)) + complex_num_value(y)));
return ptr;
}
}
// x is double
@ -3181,6 +3184,9 @@ object Cyc_fast_sum(void *data, object ptr, object x, object y) {
} else if (is_object_type(y) && type_of(y) == bignum_tag) {
assign_double(ptr, double_value(x) + mp_get_double(&bignum_value(y)));
return ptr;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, double_value(x) + complex_num_value(y));
return ptr;
}
}
// x is bignum
@ -3200,6 +3206,25 @@ object Cyc_fast_sum(void *data, object ptr, object x, object y) {
alloc_bignum(data, bn);
mp_add(&bignum_value(x), &bignum_value(y), &bignum_value(bn));
return bn;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, mp_get_double(&bignum_value(x)) + complex_num_value(y));
return ptr;
}
}
// x is complex
if (is_object_type(x) && type_of(x) == complex_num_tag) {
if (obj_is_int(y)){
assign_complex_num(ptr, complex_num_value(x) + (double)(obj_obj2int(y)));
return ptr;
} else if (is_object_type(y) && type_of(y) == double_tag) {
assign_complex_num(ptr, complex_num_value(x) + double_value(y));
return ptr;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, complex_num_value(x) + complex_num_value(y));
return ptr;
} else if (is_object_type(y) && type_of(y) == bignum_tag) {
assign_complex_num(ptr, complex_num_value(x) + mp_get_double(&bignum_value(y)));
return ptr;
}
}
// still here, raise an error
@ -3243,6 +3268,9 @@ object Cyc_fast_sub(void *data, object ptr, object x, object y) {
mp_sub(&bnx, &bignum_value(y), &bignum_value(bn));
mp_clear(&bnx);
return bn;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, ((obj_obj2int(x)) - complex_num_value(y)));
return ptr;
}
}
// x is double
@ -3256,6 +3284,9 @@ object Cyc_fast_sub(void *data, object ptr, object x, object y) {
} else if (is_object_type(y) && type_of(y) == bignum_tag) {
assign_double(ptr, double_value(x) - mp_get_double(&bignum_value(y)));
return ptr;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, double_value(x) - complex_num_value(y));
return ptr;
}
}
// x is bignum
@ -3275,6 +3306,25 @@ object Cyc_fast_sub(void *data, object ptr, object x, object y) {
alloc_bignum(data, bn);
mp_sub(&bignum_value(x), &bignum_value(y), &bignum_value(bn));
return bn;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, mp_get_double(&bignum_value(x)) - complex_num_value(y));
return ptr;
}
}
// x is complex
if (is_object_type(x) && type_of(x) == complex_num_tag) {
if (obj_is_int(y)){
assign_complex_num(ptr, complex_num_value(x) - (double)(obj_obj2int(y)));
return ptr;
} else if (is_object_type(y) && type_of(y) == double_tag) {
assign_complex_num(ptr, complex_num_value(x) - double_value(y));
return ptr;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, complex_num_value(x) - complex_num_value(y));
return ptr;
} else if (is_object_type(y) && type_of(y) == bignum_tag) {
assign_complex_num(ptr, complex_num_value(x) - mp_get_double(&bignum_value(y)));
return ptr;
}
}
// still here, raise an error
@ -3318,6 +3368,9 @@ object Cyc_fast_mul(void *data, object ptr, object x, object y) {
mp_mul(&bnx, &bignum_value(y), &bignum_value(bn));
mp_clear(&bnx);
return bn;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, ((obj_obj2int(x)) * complex_num_value(y)));
return ptr;
}
}
// x is double
@ -3331,6 +3384,9 @@ object Cyc_fast_mul(void *data, object ptr, object x, object y) {
} else if (is_object_type(y) && type_of(y) == bignum_tag) {
assign_double(ptr, double_value(x) * mp_get_double(&bignum_value(y)));
return ptr;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, double_value(x) * complex_num_value(y));
return ptr;
}
}
// x is bignum
@ -3350,6 +3406,25 @@ object Cyc_fast_mul(void *data, object ptr, object x, object y) {
alloc_bignum(data, bn);
mp_mul(&bignum_value(x), &bignum_value(y), &bignum_value(bn));
return bn;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, mp_get_double(&bignum_value(x)) * complex_num_value(y));
return ptr;
}
}
// x is complex
if (is_object_type(x) && type_of(x) == complex_num_tag) {
if (obj_is_int(y)){
assign_complex_num(ptr, complex_num_value(x) * (double)(obj_obj2int(y)));
return ptr;
} else if (is_object_type(y) && type_of(y) == double_tag) {
assign_complex_num(ptr, complex_num_value(x) * double_value(y));
return ptr;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, complex_num_value(x) * complex_num_value(y));
return ptr;
} else if (is_object_type(y) && type_of(y) == bignum_tag) {
assign_complex_num(ptr, complex_num_value(x) * mp_get_double(&bignum_value(y)));
return ptr;
}
}
// still here, raise an error
@ -3383,6 +3458,9 @@ object Cyc_fast_div(void *data, object ptr, object x, object y) {
mp_div(&bnx, &bignum_value(y), &bignum_value(bn), NULL);
mp_clear(&bnx);
return bn;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, ((obj_obj2int(x)) / complex_num_value(y)));
return ptr;
}
}
// x is double
@ -3396,6 +3474,9 @@ object Cyc_fast_div(void *data, object ptr, object x, object y) {
} else if (is_object_type(y) && type_of(y) == bignum_tag) {
assign_double(ptr, double_value(x) / mp_get_double(&bignum_value(y)));
return ptr;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, double_value(x) / complex_num_value(y));
return ptr;
}
}
// x is bignum
@ -3415,6 +3496,25 @@ object Cyc_fast_div(void *data, object ptr, object x, object y) {
alloc_bignum(data, bn);
mp_div(&bignum_value(x), &bignum_value(y), &bignum_value(bn), NULL);
return bn;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, mp_get_double(&bignum_value(x)) / complex_num_value(y));
return ptr;
}
}
// x is complex
if (is_object_type(x) && type_of(x) == complex_num_tag) {
if (obj_is_int(y)){
assign_complex_num(ptr, complex_num_value(x) / (double)(obj_obj2int(y)));
return ptr;
} else if (is_object_type(y) && type_of(y) == double_tag) {
assign_complex_num(ptr, complex_num_value(x) / double_value(y));
return ptr;
} else if (is_object_type(y) && type_of(y) == complex_num_tag) {
assign_complex_num(ptr, complex_num_value(x) / complex_num_value(y));
return ptr;
} else if (is_object_type(y) && type_of(y) == bignum_tag) {
assign_complex_num(ptr, complex_num_value(x) / mp_get_double(&bignum_value(y)));
return ptr;
}
}
// still here, raise an error