deed via Digitalmars-d-learn
2014-10-23 17:08:36 UTC
// DMD v2.066.0
// All asserts pass (!)
import std.math : sin, cos, tan, asin, acos, atan,
sinh, cosh, tanh, asinh, acosh, atanh;
alias F = double;
immutable F a = 3, b = 5;
F fmul (F a) pure { return a * b; }
F fsin (F a) pure { return sin(a); }
struct Smul { F value; this (F a) { value = a * b; } alias value
this; }
struct Ssin { F value; this (F a) { value = sin(a); } alias value
this; }
F ans_mul = fmul(a);
F ans_sin = fsin(a);
Smul smul = Smul(a);
Ssin ssin = Ssin(a);
// All combinations of a*b, fmul(a), Smul(a), ans_mul and smul
pass
// the equality test. E.g.:
assert (a*b == a*b);
assert (a*b == fmul(a));
assert (a*b == Smul(a));
assert (a*b == ans_mul);
assert (a*b == smul);
assert (fmul(a) == fmul(a));
assert (fmul(a) == Smul(a));
assert (fmul(a) == ans_mul);
assert (fmul(a) == smul);
// However, for std.math.sin it's different:
assert (sin(a) == fsin(a)); // But not in 2.065
assert (sin(a) != Ssin(a)); // ?
assert (sin(a) != ans_sin); // ?
assert (sin(a) != ssin); // ?
assert (fsin(a) != fsin(a)); // ?
assert (fsin(a) != Ssin(a)); // ?
assert (fsin(a) != ans_sin); // ?
assert (fsin(a) != ssin); // ?
// Same goes for cos, tan, asin, acos, atan:
F fcos (F a) { return cos(a); }
F ftan (F a) { return tan(a); }
F fasin (F a) { return asin(a); }
F facos (F a) { return acos(a); }
F fatan (F a) { return atan(a); }
assert (fcos(a) != fcos(a)); // ?
assert (ftan(a) != ftan(a)); // ?
assert (fasin(a) != fasin(a)); // ?
assert (facos(a) != facos(a)); // ?
assert (fatan(a) != fatan(a)); // ?
// And then it goes only downhill for
// sinh, cosh, tanh, asinh, acosh and atanh:
assert (sinh(a) != sinh(a)); // ?
assert (cosh(a) != cosh(a)); // ?
assert (tanh(a) != tanh(a)); // ?
assert (asinh(a) != asinh(a)); // ?
assert (acosh(a) != acosh(a)); // ?
assert (atanh(0.5) != atanh(0.5)); // ?
--
Why bother?
import std.algorithm : max;
F fun (F a, F b) { return max(a,b) + 1.; }
unittest { assert (gun(1, 2) == gun(2, 1)); } // Passes
F pun (F a, F b) { return sin(max(a,b)); }
unittest { assert (fun(1, 2) == fun(2, 1)); } // Fails
// All asserts pass (!)
import std.math : sin, cos, tan, asin, acos, atan,
sinh, cosh, tanh, asinh, acosh, atanh;
alias F = double;
immutable F a = 3, b = 5;
F fmul (F a) pure { return a * b; }
F fsin (F a) pure { return sin(a); }
struct Smul { F value; this (F a) { value = a * b; } alias value
this; }
struct Ssin { F value; this (F a) { value = sin(a); } alias value
this; }
F ans_mul = fmul(a);
F ans_sin = fsin(a);
Smul smul = Smul(a);
Ssin ssin = Ssin(a);
// All combinations of a*b, fmul(a), Smul(a), ans_mul and smul
pass
// the equality test. E.g.:
assert (a*b == a*b);
assert (a*b == fmul(a));
assert (a*b == Smul(a));
assert (a*b == ans_mul);
assert (a*b == smul);
assert (fmul(a) == fmul(a));
assert (fmul(a) == Smul(a));
assert (fmul(a) == ans_mul);
assert (fmul(a) == smul);
// However, for std.math.sin it's different:
assert (sin(a) == fsin(a)); // But not in 2.065
assert (sin(a) != Ssin(a)); // ?
assert (sin(a) != ans_sin); // ?
assert (sin(a) != ssin); // ?
assert (fsin(a) != fsin(a)); // ?
assert (fsin(a) != Ssin(a)); // ?
assert (fsin(a) != ans_sin); // ?
assert (fsin(a) != ssin); // ?
// Same goes for cos, tan, asin, acos, atan:
F fcos (F a) { return cos(a); }
F ftan (F a) { return tan(a); }
F fasin (F a) { return asin(a); }
F facos (F a) { return acos(a); }
F fatan (F a) { return atan(a); }
assert (fcos(a) != fcos(a)); // ?
assert (ftan(a) != ftan(a)); // ?
assert (fasin(a) != fasin(a)); // ?
assert (facos(a) != facos(a)); // ?
assert (fatan(a) != fatan(a)); // ?
// And then it goes only downhill for
// sinh, cosh, tanh, asinh, acosh and atanh:
assert (sinh(a) != sinh(a)); // ?
assert (cosh(a) != cosh(a)); // ?
assert (tanh(a) != tanh(a)); // ?
assert (asinh(a) != asinh(a)); // ?
assert (acosh(a) != acosh(a)); // ?
assert (atanh(0.5) != atanh(0.5)); // ?
--
Why bother?
import std.algorithm : max;
F fun (F a, F b) { return max(a,b) + 1.; }
unittest { assert (gun(1, 2) == gun(2, 1)); } // Passes
F pun (F a, F b) { return sin(max(a,b)); }
unittest { assert (fun(1, 2) == fun(2, 1)); } // Fails