| @safe @nogc pure nothrow unittest | |
| { | |
| import std.math.operations; | |
| import std.math.traits : isNaN; | |
| real a = NaN(1_000_000); | |
| assert(isNaN(a)); | |
| assert(getNaNPayload(a) == 1_000_000); | |
| } | |
| @safe @nogc pure nothrow unittest | |
| { | |
| import std.math.operations; | |
| import std.math.traits : isNaN; | |
| real a = NaN(1_000_000); | |
| assert(isNaN(a)); | |
| assert(getNaNPayload(a) == 1_000_000); | |
| } | |
| @safe @nogc pure nothrow unittest | |
| { | |
| import std.math.operations; | |
| assert(nextUp(1.0 - 1.0e-6).feqrel(0.999999) > 16); | |
| assert(nextUp(1.0 - real.epsilon).feqrel(1.0) > 16); | |
| } | |
| @safe pure nothrow @nogc unittest | |
| { | |
| import std.math.operations; | |
| assert( nextDown(1.0 + real.epsilon) == 1.0); | |
| } | |
| @safe pure nothrow @nogc unittest | |
| { | |
| import std.math.operations; | |
| import std.math.traits : isNaN; | |
| float a = 1; | |
| assert(is(typeof(nextafter(a, a)) == float)); | |
| assert(nextafter(a, a.infinity) > a); | |
| assert(isNaN(nextafter(a, a.nan))); | |
| assert(isNaN(nextafter(a.nan, a))); | |
| double b = 2; | |
| assert(is(typeof(nextafter(b, b)) == double)); | |
| assert(nextafter(b, b.infinity) > b); | |
| assert(isNaN(nextafter(b, b.nan))); | |
| assert(isNaN(nextafter(b.nan, b))); | |
| real c = 3; | |
| assert(is(typeof(nextafter(c, c)) == real)); | |
| assert(nextafter(c, c.infinity) > c); | |
| assert(isNaN(nextafter(c, c.nan))); | |
| assert(isNaN(nextafter(c.nan, c))); | |
| } | |
| @safe pure nothrow @nogc unittest | |
| { | |
| import std.math.operations; | |
| import std.math.traits : isNaN; | |
| assert(fdim(2.0, 0.0) == 2.0); | |
| assert(fdim(-2.0, 0.0) == 0.0); | |
| assert(fdim(real.infinity, 2.0) == real.infinity); | |
| assert(isNaN(fdim(real.nan, 2.0))); | |
| assert(isNaN(fdim(2.0, real.nan))); | |
| assert(isNaN(fdim(real.nan, real.nan))); | |
| } | |
| @safe pure nothrow @nogc unittest | |
| { | |
| import std.math.operations; | |
| import std.meta : AliasSeq; | |
| static foreach (F; AliasSeq!(float, double, real)) | |
| { | |
| assert(fmax(F(0.0), F(2.0)) == 2.0); | |
| assert(fmax(F(-2.0), 0.0) == F(0.0)); | |
| assert(fmax(F.infinity, F(2.0)) == F.infinity); | |
| assert(fmax(F.nan, F(2.0)) == F(2.0)); | |
| assert(fmax(F(2.0), F.nan) == F(2.0)); | |
| } | |
| } | |
| @safe pure nothrow @nogc unittest | |
| { | |
| import std.math.operations; | |
| import std.meta : AliasSeq; | |
| static foreach (F; AliasSeq!(float, double, real)) | |
| { | |
| assert(fmin(F(0.0), F(2.0)) == 0.0); | |
| assert(fmin(F(-2.0), F(0.0)) == -2.0); | |
| assert(fmin(F.infinity, F(2.0)) == 2.0); | |
| assert(fmin(F.nan, F(2.0)) == 2.0); | |
| assert(fmin(F(2.0), F.nan) == 2.0); | |
| } | |
| } | |
| @safe pure nothrow @nogc unittest | |
| { | |
| import std.math.operations; | |
| assert(fma(0.0, 2.0, 2.0) == 2.0); | |
| assert(fma(2.0, 2.0, 2.0) == 6.0); | |
| assert(fma(real.infinity, 2.0, 2.0) == real.infinity); | |
| assert(fma(real.nan, 2.0, 2.0) is real.nan); | |
| assert(fma(2.0, 2.0, real.nan) is real.nan); | |
| } | |
| @safe pure unittest | |
| { | |
| import std.math.operations; | |
| assert(feqrel(2.0, 2.0) == 53); | |
| assert(feqrel(2.0f, 2.0f) == 24); | |
| assert(feqrel(2.0, double.nan) == 0); | |
| // Test that numbers are within n digits of each | |
| // other by testing if feqrel > n * log2(10) | |
| // five digits | |
| assert(feqrel(2.0, 2.00001) > 16); | |
| // ten digits | |
| assert(feqrel(2.0, 2.00000000001) > 33); | |
| } | |
| @safe pure nothrow @nogc unittest | |
| { | |
| import std.math.operations; | |
| assert(isClose(1.0,0.999_999_999)); | |
| assert(isClose(0.001, 0.000_999_999_999)); | |
| assert(isClose(1_000_000_000.0,999_999_999.0)); | |
| assert(isClose(17.123_456_789, 17.123_456_78)); | |
| assert(!isClose(17.123_456_789, 17.123_45)); | |
| // use explicit 3rd parameter for less (or more) accuracy | |
| assert(isClose(17.123_456_789, 17.123_45, 1e-6)); | |
| assert(!isClose(17.123_456_789, 17.123_45, 1e-7)); | |
| // use 4th parameter when comparing close to zero | |
| assert(!isClose(1e-100, 0.0)); | |
| assert(isClose(1e-100, 0.0, 0.0, 1e-90)); | |
| assert(!isClose(1e-10, -1e-10)); | |
| assert(isClose(1e-10, -1e-10, 0.0, 1e-9)); | |
| assert(!isClose(1e-300, 1e-298)); | |
| assert(isClose(1e-300, 1e-298, 0.0, 1e-200)); | |
| // different default limits for different floating point types | |
| assert(isClose(1.0f, 0.999_99f)); | |
| assert(!isClose(1.0, 0.999_99)); | |
| static if (real.sizeof > double.sizeof) | |
| assert(!isClose(1.0L, 0.999_999_999L)); | |
| } | |
| @safe pure nothrow unittest | |
| { | |
| import std.math.operations; | |
| assert(isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001, 3.0])); | |
| assert(!isClose([1.0, 2.0], [0.999_999_999, 2.000_000_001, 3.0])); | |
| assert(!isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001])); | |
| assert(isClose([2.0, 1.999_999_999, 2.000_000_001], 2.0)); | |
| assert(isClose(2.0, [2.0, 1.999_999_999, 2.000_000_001])); | |
| } | |
| @safe unittest | |
| { | |
| import std.math.operations; | |
| assert(cmp(-double.infinity, -double.max) < 0); | |
| assert(cmp(-double.max, -100.0) < 0); | |
| assert(cmp(-100.0, -0.5) < 0); | |
| assert(cmp(-0.5, 0.0) < 0); | |
| assert(cmp(0.0, 0.5) < 0); | |
| assert(cmp(0.5, 100.0) < 0); | |
| assert(cmp(100.0, double.max) < 0); | |
| assert(cmp(double.max, double.infinity) < 0); | |
| assert(cmp(1.0, 1.0) == 0); | |
| } | |
| @safe unittest | |
| { | |
| import std.math.operations; | |
| assert(cmp(-0.0, +0.0) < 0); | |
| assert(cmp(+0.0, -0.0) > 0); | |
| } | |
| @safe unittest | |
| { | |
| import std.math.operations; | |
| assert(cmp(-double.nan, -double.infinity) < 0); | |
| assert(cmp(double.infinity, double.nan) < 0); | |
| assert(cmp(-double.nan, double.nan) < 0); | |
| } | |
| @safe unittest | |
| { | |
| import std.math.operations; | |
| assert(cmp(NaN(10), NaN(20)) < 0); | |
| assert(cmp(-NaN(20), -NaN(10)) < 0); | |
| } | |