複素数(10)


cdouble exp(cdouble z)

などを実装してきたが、
cdouble以外のcfloat、crealも同じコードで済む。
何度も同じコードを書きたくないとき、
D言語ではmixinを使うらしい。


import std.cstream;

void main(char[][] args) {
dout.writefln(pow(2.0f, 5));
dout.writefln(pow(2.0, 5));
}

template powf(T) {
T func(T x, int n) {
T y = 1;
for(int i = 0; i < n; i++) {
y *= x;
}
return y;
}
}

float pow(float x, int n) {
mixin powf!(float);
return func(x, n);
}

double pow(double x, int n) {
mixin powf!(double);
return func(x, n);
}

mixinと書いた行に、func以下が展開される。


この例では単にテンプレートを使ったほうがよいが、
実数と複素数と準拠数でコードが違う場合は、
それではうまくいかない。


本来なら、今まで示したコードをすべてまとめたいが、
あまり時間がないので、
expだけまとめる。




import std.cstream;
import std.math;

void main(char[][] args) {
dout.writefln(exp(0.1f));
dout.writefln(exp(0.1));
dout.writefln(exp(cast(real)0.1));
dout.writefln(exp(0.1+0i));
dout.writefln(exp(0.1i));
}

template rexp(T, R) {
R func(T x) {
return std.math.exp(x);
}
}

template cexp(T, R) {
R func(T z) {
auto im = z.im;
return exp(z.re) * (cos(im) + 1i * sin(im));
}
}

template iexp(T, R) {
R func(T z) {
auto y = z.im;
return cos(y) + 1i * sin(y);
}
}

float exp(float x) {
mixin rexp!(float, float);
return func(x);
}

double exp(double x) {
mixin rexp!(double, double);
return func(x);
}

real exp(real x) {
mixin rexp!(real, real);
return func(x);
}

cfloat exp(cfloat x) {
mixin cexp!(cfloat, cfloat);
return func(x);
}

cdouble exp(cdouble x) {
mixin cexp!(cdouble, cdouble);
return func(x);
}

creal exp(creal x) {
mixin cexp!(creal, creal);
return func(x);
}

cdouble exp(idouble x) {
mixin iexp!(idouble, cdouble);
return func(x);
}