Sourcestd/math/operations.d
NaN(ulongpayload);import std.math.traits : isNaN;real a =NaN(1_000_000);assert(isNaN(a));writeln(getNaNPayload(a));// 1_000_000
getNaNPayload(realx);import std.math.traits : isNaN;real a = NaN(1_000_000);assert(isNaN(a));writeln(getNaNPayload(a));// 1_000_000
nextUp(realx);nextUp(doublex);nextUp(floatx);| x | nextUp(x) |
|---|---|
| -∞ | -real.max |
| ±0.0 | real.min_normal*real.epsilon |
| real.max | ∞ |
| ∞ | ∞ |
| NAN | NAN |
assert(nextUp(1.0 - 1.0e-6).feqrel(0.999999) > 16);assert(nextUp(1.0 -real.epsilon).feqrel(1.0) > 16);
nextDown(realx);nextDown(doublex);nextDown(floatx);| x | nextDown(x) |
|---|---|
| ∞ | real.max |
| ±0.0 | -real.min_normal*real.epsilon |
| -real.max | -∞ |
| -∞ | -∞ |
| NAN | NAN |
writeln(nextDown(1.0 +real.epsilon));// 1.0
nextafter(T)(const Tx, const Ty);RemarksThis function is not generally very useful; it's almost always better to use the faster functions nextUp() or nextDown() instead.
The FE_INEXACT and FE_OVERFLOW exceptions will be raised if x is finite and the function result is infinite. The FE_INEXACT and FE_UNDERFLOW exceptions will be raised if the function value is subnormal, and x is not equal to y.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)));
fdim(realx, realy);x-y, 0).| x, y | fdim(x, y) |
|---|---|
| x > y | x - y |
| x <= y | +0.0 |
import std.math.traits : isNaN;writeln(fdim(2.0, 0.0));// 2.0writeln(fdim(-2.0, 0.0));// 0.0writeln(fdim(real.infinity, 2.0));// real.infinityassert(isNaN(fdim(real.nan, 2.0)));assert(isNaN(fdim(2.0,real.nan)));assert(isNaN(fdim(real.nan,real.nan)));
fmax(F)(const Fx, const Fy)x andy.import std.meta : AliasSeq;staticforeach (F; AliasSeq!(float,double,real)){ writeln(fmax(F(0.0), F(2.0)));// 2.0 writeln(fmax(F(-2.0), 0.0));// F(0.0) writeln(fmax(F.infinity, F(2.0)));// F.infinity writeln(fmax(F.nan, F(2.0)));// F(2.0) writeln(fmax(F(2.0), F.nan));// F(2.0)}
fmin(F)(const Fx, const Fy)x andy.import std.meta : AliasSeq;staticforeach (F; AliasSeq!(float,double,real)){ writeln(fmin(F(0.0), F(2.0)));// 0.0 writeln(fmin(F(-2.0), F(0.0)));// -2.0 writeln(fmin(F.infinity, F(2.0)));// 2.0 writeln(fmin(F.nan, F(2.0)));// 2.0 writeln(fmin(F(2.0), F.nan));// 2.0}
fma(realx, realy, realz);writeln(fma(0.0, 2.0, 2.0));// 2.0writeln(fma(2.0, 2.0, 2.0));// 6.0writeln(fma(real.infinity, 2.0, 2.0));// real.infinityassert(fma(real.nan, 2.0, 2.0)isreal.nan);assert(fma(2.0, 2.0,real.nan)isreal.nan);
feqrel(X)(const Xx, const Xy)| x | y | feqrel(x, y) |
|---|---|---|
| x | x | real.mant_dig |
| x | >= 2*x | 0 |
| x | <= x/2 | 0 |
| NAN | any | 0 |
| any | NAN | 0 |
writeln(feqrel(2.0, 2.0));// 53writeln(feqrel(2.0f, 2.0f));// 24writeln(feqrel(2.0,double.nan));// 0// Test that numbers are within n digits of each// other by testing if feqrel > n * log2(10)// five digitsassert(feqrel(2.0, 2.00001) > 16);// ten digitsassert(feqrel(2.0, 2.00000000001) > 33);
approxEqual(T, U, V)(Tvalue, Ureference, VmaxRelDiff = 0.01, VmaxAbsDiff = 1e-05);WarningThis template is considered out-dated. It will be removed from Phobos in 2.106.0. Please useisClose instead. To achieve a similar behaviour toapproxEqual(a, b) useisClose(a, b, 1e-2, 1e-5). In case of comparing to 0.0,isClose(a, b, 0.0, eps) should be used, whereeps represents the accepted deviation from 0.0."
Tvalue | Value to compare. |
Ureference | Reference value. |
VmaxRelDiff | Maximum allowable difference relative toreference. Setting to 0.0 disables this check. Defaults to1e-2. |
VmaxAbsDiff | Maximum absolute difference. This is mainly usefull for comparing values to zero. Setting to 0.0 disables this check. Defaults to1e-5. |
value is approximately equal toreference under either criterium. It is sufficient, whenvalue satisfies one of the two criteria. If one item is a range, and the other is a single value, then the result is the logical and-ing of callingapproxEqual on each element of the ranged item against the single item. If both items are ranges, thenapproxEqual returnstrue if and only if the ranges have the same number of elements and ifapproxEqual evaluates totrue for each pair of elements.isClose(T, U, V = CommonType!(FloatingPointBaseType!T, FloatingPointBaseType!U))(Tlhs, Urhs, VmaxRelDiff = CommonDefaultFor!(T, U), VmaxAbsDiff = 0.0);Tlhs | First item to compare. |
Urhs | Second item to compare. |
VmaxRelDiff | Maximum allowable relative difference. Setting to 0.0 disables this check. Default depends on the type oflhs andrhs: It is approximately half the number of decimal digits of precision of the smaller type. |
VmaxAbsDiff | Maximum absolute difference. This is mainly usefull for comparing values to zero. Setting to 0.0 disables this check. Defaults to0.0. |
isClose on each element of the ranged item against the single item. If both items are ranges, thenisClose returnstrue if and only if the ranges have the same number of elements and ifisClose evaluates totrue for each pair of elements.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) accuracyassert(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 zeroassert(!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 typesassert(isClose(1.0f, 0.999_99f));assert(!isClose(1.0, 0.999_99));staticif (real.sizeof >double.sizeof)assert(!isClose(1.0L, 0.999_999_999L));
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]));
cmp(T)(const(T)x, const(T)y)x precedesy in the order specified above; 0 ifx andy are identical, and positive value otherwise.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);writeln(cmp(1.0, 1.0));// 0
assert(cmp(-0.0, +0.0) < 0);assert(cmp(+0.0, -0.0) > 0);
assert(cmp(-double.nan, -double.infinity) < 0);assert(cmp(double.infinity,double.nan) < 0);assert(cmp(-double.nan,double.nan) < 0);
assert(cmp(NaN(10), NaN(20)) < 0);assert(cmp(-NaN(20), -NaN(10)) < 0);