summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-cmath/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-02-06 00:08:25 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-02-06 00:08:25 +0900
commita6994f51c8504b845542d25b092cd2b871053514 (patch)
tree387cfdd6c6d50be28d0b43e6ea87b1e789149031 /mrbgems/mruby-cmath/src
parenta0050541d1a4743721f805a71abfd9c898877fc7 (diff)
downloadmruby-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.c61
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));
}