blob: b0678f10c364de9002fcedf90263ebe0eea0dd99 [file] [log] [blame]
@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);
}