diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-02-06 00:08:25 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-02-06 00:08:25 +0900 |
| commit | a6994f51c8504b845542d25b092cd2b871053514 (patch) | |
| tree | 387cfdd6c6d50be28d0b43e6ea87b1e789149031 /mrbgems/mruby-cmath/src | |
| parent | a0050541d1a4743721f805a71abfd9c898877fc7 (diff) | |
| download | mruby-a6994f51c8504b845542d25b092cd2b871053514.tar.gz mruby-a6994f51c8504b845542d25b092cd2b871053514.zip | |
Update `mruby-cmath` to support MSVC complex.
* Use `_Complex` instead of `complex` (MSYS2 do not support `complex`)
* Use `_Dcomplex` instead of `_Complex` on MSCV
* Avoid operator division and multiplication of complex
Diffstat (limited to 'mrbgems/mruby-cmath/src')
| -rw-r--r-- | mrbgems/mruby-cmath/src/cmath.c | 61 |
1 files changed, 49 insertions, 12 deletions
diff --git a/mrbgems/mruby-cmath/src/cmath.c b/mrbgems/mruby-cmath/src/cmath.c index e938c77b1..9eeadd019 100644 --- a/mrbgems/mruby-cmath/src/cmath.c +++ b/mrbgems/mruby-cmath/src/cmath.c @@ -45,11 +45,50 @@ cmath_get_complex(mrb_state *mrb, mrb_value c, mrb_float *r, mrb_float *i) } #ifdef MRB_USE_FLOAT32 -typedef float complex mrb_complex; #define F(x) x##f #else -typedef double complex mrb_complex; +#endif #define F(x) x + +#ifdef _WIN32 + +#ifdef MRB_USE_FLOAT32 +typedef _Fcomplex mrb_complex; +#define CX(r,i) _FCbuild(r,i) +#define CXMUL(x,y) _FCmulcr(x,y) +#else +typedef _Dcomplex mrb_complex; +#define CX(r,i) _Cbuild(r,i) +#define CXMUL(x,y) _Cmulcr(x,y) +#endif + +static mrb_complex +CXDIVf(mrb_complex x, mrb_float y) +{ + return CX(creal(x)/y, cimag(x)/y); +} + +static mrb_complex +CXDIVc(mrb_complex x, mrb_complex y) +{ + mrb_complex n=CXMUL(x, F(conj)(y)); + mrb_complex d=_CXMUL(y, F(conj)(y)); + + return CX(creal(n)/creal(d), cimag(n)/cimag(d)); +} + +#else + +#ifdef MRB_USE_FLOAT32 +typedef float _Complex mrb_complex; +#else +typedef double _Complex mrb_complex; +#endif + +#define CX(r,i) (r+i*I) +#define CXDIVf(x,y) (x)/(y) +#define CXDIVc(x,y) (x)/(y) + #endif #define DEF_CMATH_METHOD(name) \ @@ -59,7 +98,7 @@ cmath_ ## name(mrb_state *mrb, mrb_value self)\ mrb_value z = mrb_get_arg1(mrb);\ mrb_float real, imag;\ if (cmath_get_complex(mrb, z, &real, &imag)) {\ - mrb_complex c = real + imag*I;\ + mrb_complex c = CX(real,imag);\ c = F(c ## name)(c);\ return mrb_complex_new(mrb, creal(c), cimag(c));\ }\ @@ -79,11 +118,9 @@ cmath_log(mrb_state *mrb, mrb_value self) { mrb_int n = mrb_get_args(mrb, "o|f", &z, &base); if (n == 1) base = M_E; if (cmath_get_complex(mrb, z, &real, &imag) || real < 0.0) { - mrb_complex c = real + imag*I; + mrb_complex c = CX(real,imag); c = F(clog)(c); - if (n == 2) { - c /= clog(base); - } + if (n == 2) c = CXDIVc(c, F(clog)(base)); return mrb_complex_new(mrb, creal(c), cimag(c)); } if (n == 1) return mrb_float_value(mrb, F(log)(real)); @@ -96,8 +133,8 @@ cmath_log10(mrb_state *mrb, mrb_value self) { mrb_value z = mrb_get_arg1(mrb); mrb_float real, imag; if (cmath_get_complex(mrb, z, &real, &imag) || real < 0.0) { - mrb_complex c = real + imag*I; - c = F(clog)(c)/log(10); + mrb_complex c = CX(real,imag); + c = CXDIVf(F(clog)(c),log(10)); return mrb_complex_new(mrb, creal(c), cimag(c)); } return mrb_float_value(mrb, F(log10)(real)); @@ -109,8 +146,8 @@ cmath_log2(mrb_state *mrb, mrb_value self) { mrb_value z = mrb_get_arg1(mrb); mrb_float real, imag; if (cmath_get_complex(mrb, z, &real, &imag) || real < 0.0) { - mrb_complex c = real + imag*I; - c = F(clog)(c)/log(2); + mrb_complex c = CX(real,imag); + c = CXDIVf(F(clog)(c),log(2)); return mrb_complex_new(mrb, creal(c), cimag(c)); } return mrb_float_value(mrb, F(log2)(real)); @@ -122,7 +159,7 @@ cmath_sqrt(mrb_state *mrb, mrb_value self) { mrb_value z = mrb_get_arg1(mrb); mrb_float real, imag; if (cmath_get_complex(mrb, z, &real, &imag) || real < 0.0) { - mrb_complex c = real + imag*I; + mrb_complex c = CX(real,imag); c = F(csqrt)(c); return mrb_complex_new(mrb, creal(c), cimag(c)); } |
