8 #include "ruby/config.h" 11 # define _USE_MATH_DEFINES 1 19 #define ZERO INT2FIX(0) 20 #define ONE INT2FIX(1) 21 #define TWO INT2FIX(2) 22 #define RFLOAT_0 DBL2NUM(0) 23 #if defined(HAVE_SIGNBIT) && defined(__GNUC__) && defined(__sun) && \ 41 #define f_boolcast(x) ((x) ? Qtrue : Qfalse) 45 f_##n(VALUE x, VALUE y)\ 47 return rb_funcall(x, (op), 1, y);\ 54 return rb_funcall(x, id_##n, 0);\ 59 f_##n(VALUE x, VALUE y)\ 61 return rb_funcall(x, id_##n, 1, y);\ 68 return rb_funcall(rb_mMath, id_##n, 1, x);\ 73 m_##n(VALUE x, VALUE y)\ 75 return rb_funcall(rb_mMath, id_##n, 2, x, y);\ 78 #define PRESERVE_SIGNEDZERO 83 #ifndef PRESERVE_SIGNEDZERO 120 #ifndef PRESERVE_SIGNEDZERO 146 #ifndef PRESERVE_SIGNEDZERO 223 #define f_positive_p(x) (!f_negative_p(x)) 238 #define f_nonzero_p(x) (!f_zero_p(x)) 252 #define k_exact_p(x) (!RB_FLOAT_TYPE_P(x)) 254 #define k_exact_zero_p(x) (k_exact_p(x) && f_zero_p(x)) 256 #define get_dat1(x) \ 257 struct RComplex *dat = RCOMPLEX(x) 259 #define get_dat2(x,y) \ 260 struct RComplex *adat = RCOMPLEX(x), *bdat = RCOMPLEX(y) 318 #ifdef CANONICALIZATION_FOR_MATHN 328 canonicalization =
f;
331 #define canonicalization 0 354 if (
f_zero_p(imag) && canonicalization)
358 if (f_real_p(real) && f_real_p(imag))
360 else if (f_real_p(real)) {
364 f_sub(real, dat->imag),
367 else if (f_real_p(imag)) {
372 f_add(dat->imag, imag));
378 f_sub(adat->real, bdat->imag),
379 f_add(adat->imag, bdat->real));
460 inline static VALUE \ 461 m_##n##_bang(VALUE x)\ 463 return rb_math_##n(x);\ 483 return m_cos_bang(x);
487 f_mul(m_cos_bang(dat->real),
488 m_cosh_bang(dat->imag)),
490 m_sinh_bang(dat->imag)));
498 return m_sin_bang(x);
502 f_mul(m_sin_bang(dat->real),
503 m_cosh_bang(dat->imag)),
504 f_mul(m_cos_bang(dat->real),
505 m_sinh_bang(dat->imag)));
532 return m_sqrt_bang(x);
545 if (canonicalization)
return x;
552 if (canonicalization)
return x;
565 const double real = abs * cos(arg), imag = abs * sin(arg);
567 if (canonicalization && imag == 0.0)
return x;
573 if (canonicalization &&
f_zero_p(y))
return x;
601 if (canonicalization)
return abs;
680 real =
f_add(adat->real, bdat->real);
681 imag =
f_add(adat->imag, bdat->imag);
689 f_add(dat->real, other), dat->imag);
714 real =
f_sub(adat->real, bdat->real);
715 imag =
f_sub(adat->imag, bdat->imag);
723 f_sub(dat->real, other), dat->imag);
758 VALUE areal, aimag, breal, bimag;
759 int arzero, aizero, brzero, bizero;
763 arzero =
f_zero_p(areal = adat->real);
764 aizero =
f_zero_p(aimag = adat->imag);
765 brzero =
f_zero_p(breal = bdat->real);
766 bizero =
f_zero_p(bimag = bdat->imag);
768 safe_mul(aimag, bimag, aizero, bizero));
770 safe_mul(aimag, breal, aizero, brzero));
778 f_mul(dat->real, other),
779 f_mul(dat->imag, other));
783 #define nucomp_mul rb_complex_mul 799 r = (*func)(bdat->imag, bdat->real);
807 f_mul(adat->imag, r)), n),
809 f_mul(adat->real, r)), n));
814 r = (*func)(bdat->real, bdat->imag);
831 (*
func)(dat->real, other),
832 (*
func)(dat->imag, other));
837 #define rb_raise_zerodiv() rb_raise(rb_eZeroDivError, "divided by 0") 858 #define nucomp_quo nucomp_div 906 VALUE r, theta, nr, ntheta;
913 nr = m_exp_bang(
f_sub(
f_mul(dat->real, m_log_bang(r)),
914 f_mul(dat->imag, theta)));
916 f_mul(dat->imag, m_log_bang(r)));
942 f_mul(dat->imag, dat->imag)),
957 rb_warn(
"in a**b, b may be too big");
963 f_mul(theta, other));
1055 f_mul(dat->imag, dat->imag));
1124 nucomp_true(
VALUE self)
1145 nucomp_exact_p(
VALUE self)
1153 nucomp_inexact_p(
VALUE self)
1264 s = (*func)(dat->real);
1317 #define FINITE_TYPE_P(v) (RB_INTEGER_TYPE_P(v) || RB_TYPE_P(v, T_RATIONAL)) 1368 return INT2FIX(f < 0 ? -1 : 1);
1489 return f_to_i(dat->real);
1512 return f_to_f(dat->real);
1537 return f_to_r(dat->real);
1611 return (c ==
'-' || c ==
'+');
1631 return isdigit((
unsigned char)c);
1661 }
while (**s ==
'_');
1668 return (c ==
'e' || c ==
'E');
1743 return (c ==
'i' || c ==
'I' ||
1744 c ==
'j' || c ==
'J');
1752 if (strpbrk(s,
".eE"))
1759 VALUE *ret,
char **b)
1771 num =
INT2FIX((sign ==
'-') ? -1 : + 1);
1815 num2 =
INT2FIX((sign ==
'-') ? -1 : + 1);
1842 while (isspace((
unsigned char)**s))
1953 VALUE a1, a2, backref;
2005 (!f_real_p(a1) || !f_real_p(a2)))
2055 return f_mul(
self,
self);
2188 #define rb_intern(str) rb_intern_const(str) 2190 assert(fprintf(stderr,
"assert() is now active\n"));
static int read_rat_nos(const char **s, int strict, char **b)
RUBY_EXTERN VALUE rb_cString
static VALUE nucomp_expt(VALUE self, VALUE other)
VALUE rb_rational_cmp(VALUE self, VALUE other)
static int islettere(int c)
static int cmp(VALUE x, VALUE y)
static VALUE f_mul(VALUE x, VALUE y)
static VALUE nucomp_rationalize(int argc, VALUE *argv, VALUE self)
VALUE rb_int_uminus(VALUE num)
VALUE rb_complex_set_imag(VALUE cmp, VALUE i)
RUBY_EXTERN VALUE rb_cFloat
VALUE rb_num_coerce_bin(VALUE, VALUE, ID)
static VALUE safe_mul(VALUE a, VALUE b, int az, int bz)
size_t strlen(const char *)
void rb_backref_set(VALUE)
static VALUE nucomp_to_f(VALUE self)
static VALUE nucomp_denominator(VALUE self)
VALUE rb_cstr_to_rat(const char *, int)
RUBY_EXTERN int signbit(double x)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
VALUE rb_complex_set_real(VALUE cmp, VALUE r)
static VALUE nilclass_to_c(VALUE self)
static VALUE nucomp_sub(VALUE self, VALUE other)
#define rb_usascii_str_new2
static VALUE nucomp_imag(VALUE self)
static VALUE f_complex_new2(VALUE klass, VALUE x, VALUE y)
VALUE rb_float_abs(VALUE flt)
VALUE rb_complex_polar(VALUE x, VALUE y)
static int isimagunit(int c)
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
static VALUE nucomp_s_new(int argc, VALUE *argv, VALUE klass)
void rb_must_asciicompat(VALUE)
SSL_METHOD *(* func)(void)
static int read_rat(const char **s, int strict, char **b)
VALUE rb_str_concat(VALUE, VALUE)
st_index_t rb_memhash(const void *ptr, long len)
VALUE rb_lcm(VALUE x, VALUE y)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
static VALUE string_to_c_strict(VALUE self)
static VALUE nucomp_to_s(VALUE self)
VALUE rb_backref_get(void)
static int f_tpositive_p(VALUE x)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_ivar_get(VALUE, ID)
static int k_numeric_p(VALUE x)
VALUE rb_convert_type(VALUE, int, const char *, const char *)
static VALUE f_complex_polar(VALUE klass, VALUE x, VALUE y)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
static VALUE nucomp_abs(VALUE self)
VALUE rb_int_gt(VALUE x, VALUE y)
static VALUE nucomp_negate(VALUE self)
double rb_str_to_dbl(VALUE, int)
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
RUBY_EXTERN VALUE rb_mMath
#define RCOMPLEX_SET_IMAG(cmp, i)
static VALUE m_sin(VALUE x)
static VALUE nucomp_to_c(VALUE self)
static VALUE f_negative_p(VALUE x)
static VALUE nucomp_arg(VALUE self)
void rb_undef_method(VALUE klass, const char *name)
int rb_cmpint(VALUE val, VALUE a, VALUE b)
static VALUE nucomp_inspect(VALUE self)
#define rb_complex_new1(x)
static VALUE f_add(VALUE x, VALUE y)
static VALUE str2num(char *s)
static VALUE numeric_rect(VALUE self)
#define NEWOBJ_OF(obj, type, klass, flags)
#define RB_TYPE_P(obj, type)
static VALUE nucomp_eqeq_p(VALUE self, VALUE other)
static VALUE numeric_abs2(VALUE self)
static VALUE nucomp_eql_p(VALUE self, VALUE other)
VALUE rb_complex_mul(VALUE self, VALUE other)
static VALUE f_complex_new_bang1(VALUE klass, VALUE x)
RUBY_EXTERN VALUE rb_cObject
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
static VALUE nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
VALUE rb_str_cat2(VALUE, const char *)
#define INT_NEGATIVE_P(x)
int rb_num_negative_p(VALUE)
static int parse_comp(const char *s, int strict, VALUE *num)
static VALUE nucomp_real(VALUE self)
static int f_signbit(VALUE x)
static VALUE string_to_c(VALUE self)
static VALUE numeric_conj(VALUE self)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
VALUE rb_complex_sqrt(VALUE x)
static VALUE nucomp_s_alloc(VALUE klass)
void rb_define_const(VALUE, const char *, VALUE)
#define k_exact_zero_p(x)
static VALUE float_arg(VALUE self)
static int read_den(const char **s, int strict, char **b)
#define ALLOCV_N(type, v, n)
static VALUE f_sub(VALUE x, VALUE y)
#define RUBY_FUNC_EXPORTED
RUBY_EXTERN int isinf(double)
static int read_comp(const char **s, int strict, VALUE *ret, char **b)
VALUE rb_int_abs(VALUE num)
static VALUE nucomp_fdiv(VALUE self, VALUE other)
VALUE rb_const_get(VALUE, ID)
VALUE rb_float_gt(VALUE x, VALUE y)
#define rb_complex_new2(x, y)
static VALUE numeric_arg(VALUE self)
static VALUE nucomp_to_r(VALUE self)
VALUE rb_math_atan2(VALUE, VALUE)
static VALUE f_to_f(VALUE x)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
static VALUE f_div(VALUE x, VALUE y)
VALUE rb_ivar_set(VALUE, ID, VALUE)
unsigned char buf[MIME_BUF_SIZE]
VALUE rb_assoc_new(VALUE car, VALUE cdr)
void rb_undef_methods_from(VALUE klass, VALUE super)
#define RGENGC_WB_PROTECTED_COMPLEX
char * strchr(char *, char)
void rb_match_busy(VALUE)
VALUE rb_Complex(VALUE x, VALUE y)
static VALUE nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
RUBY_EXTERN VALUE rb_cNumeric
VALUE rb_complex_new(VALUE x, VALUE y)
static VALUE rb_complex_infinite_p(VALUE self)
static void nucomp_real_check(VALUE num)
#define RB_FLOAT_TYPE_P(obj)
static VALUE numeric_to_c(VALUE self)
static void skip_ws(const char **s)
static VALUE nucomp_numerator(VALUE self)
void rb_str_modify(VALUE)
static VALUE nucomp_s_canonicalize_internal(VALUE klass, VALUE real, VALUE imag)
VALUE rb_equal(VALUE, VALUE)
void nucomp_canonicalization(int)
static VALUE nucomp_abs2(VALUE self)
static VALUE nucomp_to_i(VALUE self)
static int rb_isdigit(int c)
#define RARRAY_AREF(a, i)
#define FIXNUM_ZERO_P(num)
VALUE rb_complex_raw(VALUE x, VALUE y)
static VALUE rb_complex_finite_p(VALUE self)
VALUE rb_rational_uminus(VALUE self)
static VALUE nucomp_dumper(VALUE self)
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
static VALUE f_eqeq_p(VALUE x, VALUE y)
static VALUE nucomp_rect(VALUE self)
static VALUE nucomp_marshal_load(VALUE self, VALUE a)
static VALUE f_divide(VALUE self, VALUE other, VALUE(*func)(VALUE, VALUE), ID id)
VALUE rb_rational_abs(VALUE self)
static VALUE nucomp_s_new_internal(VALUE klass, VALUE real, VALUE imag)
VALUE rb_complex_plus(VALUE self, VALUE other)
static int f_gt_p(VALUE x, VALUE y)
static int read_sign(const char **s, char **b)
static VALUE numeric_imag(VALUE self)
static VALUE nucomp_loader(VALUE self, VALUE a)
static VALUE nucomp_hash(VALUE self)
static VALUE nucomp_conj(VALUE self)
static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
VALUE rb_complex_abs(VALUE cmp)
static VALUE f_complex_new_bang2(VALUE klass, VALUE x, VALUE y)
static VALUE nucomp_coerce(VALUE self, VALUE other)
static int read_digits(const char **s, int strict, char **b)
#define RCOMPLEX_SET_REAL(cmp, r)
static VALUE numeric_polar(VALUE self)
void rb_copy_generic_ivar(VALUE, VALUE)
static VALUE nucomp_marshal_dump(VALUE self)
VALUE rb_math_hypot(VALUE, VALUE)
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
static VALUE f_reciprocal(VALUE x)
static int f_zero_p(VALUE x)
static int f_kind_of_p(VALUE x, VALUE c)
VALUE rb_math_log(int argc, const VALUE *argv)
#define RB_INTEGER_TYPE_P(obj)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
void rb_provide(const char *)
void rb_warn(const char *fmt,...)
static int isdecimal(int c)
RUBY_EXTERN VALUE rb_cNilClass
double rb_cstr_to_dbl(const char *, int)
static VALUE nucomp_false(VALUE self)
static VALUE numeric_real(VALUE self)
static VALUE nucomp_div(VALUE self, VALUE other)
static VALUE nucomp_polar(VALUE self)
VALUE rb_float_uminus(VALUE num)
static VALUE f_format(VALUE self, VALUE(*func)(VALUE))
static int read_num(const char **s, int strict, char **b)
VALUE rb_obj_class(VALUE)