Report a bug
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# std.math.operations

This is a submodule of std.math.
It contains several functions for work with floating point numbers.
Authors:
Walter Bright, Don Clugston, Conversion of CEPHES math library to D by Iain Buclaw and David Nadlinger
pure nothrow @nogc @trusted real `NaN`(ulong `payload`);
Create a quiet NAN, storing an integer inside the payload.
For floats, the largest possible payload is 0x3F_FFFF. For doubles, it is 0x3_FFFF_FFFF_FFFF. For 80-bit or 128-bit reals, it is 0x3FFF_FFFF_FFFF_FFFF.
Examples:
```import std.math.traits : isNaN;

real a = NaN(1_000_000);
assert(isNaN(a));
```
pure nothrow @nogc @trusted ulong `getNaNPayload`(real `x`);
Extract an integral payload from a NAN.
Returns:
the integer payload as a ulong.
For floats, the largest possible payload is 0x3F_FFFF. For doubles, it is 0x3_FFFF_FFFF_FFFF. For 80-bit or 128-bit reals, it is 0x3FFF_FFFF_FFFF_FFFF.
Examples:
```import std.math.traits : isNaN;

real a = NaN(1_000_000);
assert(isNaN(a));
```
pure nothrow @nogc @trusted real `nextUp`(real `x`);

pure nothrow @nogc @trusted double `nextUp`(double `x`);

pure nothrow @nogc @trusted float `nextUp`(float `x`);
Calculate the next largest floating point value after x.
Return the least number greater than x that is representable as a real; thus, it gives the next point on the IEEE number line.
Special Values
x nextUp(x)
-∞ -real.max
±0.0 real.min_normal*real.epsilon
real.max
NAN NAN
Examples:
```assert(nextUp(1.0 - 1.0e-6).feqrel(0.999999) > 16);
assert(nextUp(1.0 - real.epsilon).feqrel(1.0) > 16);
```
pure nothrow @nogc @safe real `nextDown`(real `x`);

pure nothrow @nogc @safe double `nextDown`(double `x`);

pure nothrow @nogc @safe float `nextDown`(float `x`);
Calculate the next smallest floating point value before x.
Return the greatest number less than x that is representable as a real; thus, it gives the previous point on the IEEE number line.
Special Values
x nextDown(x)
real.max
±0.0 -real.min_normal*real.epsilon
-real.max -∞
-∞ -∞
NAN NAN
Examples:
```writeln(nextDown(1.0 + real.epsilon)); // 1.0
```
pure nothrow @nogc @safe T `nextafter`(T)(const T `x`, const T `y`);
Calculates the next representable value after x in the direction of y.
If y > x, the result will be the next largest floating-point value; if y < x, the result will be the next smallest value. If x == y, the result is y. If x or y is a NaN, the result is a NaN.

Remarks This 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.

Examples:
```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)));
```
pure nothrow @nogc @safe real `fdim`(real `x`, real `y`);
Returns the positive difference between x and y.
Equivalent to fmax(`x`-`y`, 0).
Returns:
Special Values
x, y fdim(x, y)
x > y x - y
x <= y +0.0
Examples:
```import std.math.traits : isNaN;

writeln(fdim(2.0, 0.0)); // 2.0
writeln(fdim(-2.0, 0.0)); // 0.0
writeln(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)));
```
pure nothrow @nogc @safe F `fmax`(F)(const F `x`, const F `y`)
if (__traits(isFloating, F));
Returns the larger of `x` and `y`.
If one of the arguments is a NaN, the other is returned.
std.algorithm.comparison.max is faster because it does not perform the isNaN test.
Examples:
```import std.meta : AliasSeq;
static foreach (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)
}
```
pure nothrow @nogc @safe F `fmin`(F)(const F `x`, const F `y`)
if (__traits(isFloating, F));
Returns the smaller of `x` and `y`.
If one of the arguments is a NaN, the other is returned.
std.algorithm.comparison.min is faster because it does not perform the isNaN test.
Examples:
```import std.meta : AliasSeq;
static foreach (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
}
```
pure nothrow @nogc @safe real `fma`(real `x`, real `y`, real `z`);
Returns (x * y) + z, rounding only once according to the current rounding mode.
Bugs:
Not currently implemented - rounds twice.
Examples:
```writeln(fma(0.0, 2.0, 2.0)); // 2.0
writeln(fma(2.0, 2.0, 2.0)); // 6.0
writeln(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);
```
pure nothrow @nogc @trusted int `feqrel`(X)(const X `x`, const X `y`)
if (isFloatingPoint!X);
To what precision is x equal to y?
Returns:
the number of mantissa bits which are equal in x and y. eg, 0x1.F8p+60 and 0x1.F1p+60 are equal to 5 bits of precision.
Special Values
x y feqrel(x, y)
x x real.mant_dig
x >= 2*x 0
x <= x/2 0
NAN any 0
any NAN 0
Examples:
```writeln(feqrel(2.0, 2.0)); // 53
writeln(feqrel(2.0f, 2.0f)); // 24
writeln(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);
```
bool `approxEqual`(T, U, V)(T `value`, U `reference`, V `maxRelDiff` = 0.01, V `maxAbsDiff` = 1e-05);
Computes whether a values is approximately equal to a reference value, admitting a maximum relative difference, and a maximum absolute difference.

Warning This template is considered out-dated. It will be removed from Phobos in 2.106.0. Please use isClose instead. To achieve a similar behaviour to `approxEqual`(a, b) use isClose(a, b, 1e-2, 1e-5). In case of comparing to 0.0, isClose(a, b, 0.0, eps) should be used, where eps represents the accepted deviation from 0.0."

Parameters:
 T `value` Value to compare. U `reference` Reference value. V `maxRelDiff` Maximum allowable difference relative to `reference`. Setting to 0.0 disables this check. Defaults to 1e-2. V `maxAbsDiff` Maximum absolute difference. This is mainly usefull for comparing values to zero. Setting to 0.0 disables this check. Defaults to 1e-5.
Returns:
true if `value` is approximately equal to `reference` under either criterium. It is sufficient, when `value` 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 calling `approxEqual` on each element of the ranged item against the single item. If both items are ranges, then `approxEqual` returns true if and only if the ranges have the same number of elements and if `approxEqual` evaluates to true for each pair of elements.
Use feqrel to get the number of equal bits in the mantissa.
bool `isClose`(T, U, V = CommonType!(FloatingPointBaseType!T, FloatingPointBaseType!U))(T `lhs`, U `rhs`, V `maxRelDiff` = CommonDefaultFor!(T, U), V `maxAbsDiff` = 0.0);
Computes whether two values are approximately equal, admitting a maximum relative difference, and a maximum absolute difference.
Parameters:
 T `lhs` First item to compare. U `rhs` Second item to compare. V `maxRelDiff` Maximum allowable relative difference. Setting to 0.0 disables this check. Default depends on the type of `lhs` and `rhs`: It is approximately half the number of decimal digits of precision of the smaller type. V `maxAbsDiff` Maximum absolute difference. This is mainly usefull for comparing values to zero. Setting to 0.0 disables this check. Defaults to 0.0.
Returns:
true if the two items are approximately equal under either criterium. It is sufficient, when value 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 calling `isClose` on each element of the ranged item against the single item. If both items are ranges, then `isClose` returns true if and only if the ranges have the same number of elements and if `isClose` evaluates to true for each pair of elements.
Use feqrel to get the number of equal bits in the mantissa.
Examples:
```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));
```
Examples:
```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]));
```
pure nothrow @nogc @trusted int `cmp`(T)(const(T) `x`, const(T) `y`)
if (isFloatingPoint!T);
Defines a total order on all floating-point numbers.
The order is defined as follows:
• All numbers in [-∞, +∞] are ordered the same way as by built-in comparison, with the exception of -0.0, which is less than +0.0;
• If the sign bit is set (that is, it's 'negative'), NAN is less than any number; if the sign bit is not set (it is 'positive'), NAN is greater than any number;
• NANs of the same sign are ordered by the payload ('negative' ones - in reverse order).
Returns:
negative value if `x` precedes `y` in the order specified above; 0 if `x` and `y` are identical, and positive value otherwise.
Standards:
Conforms to IEEE 754-2008
Examples:
Most numbers are ordered naturally.
```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
```
Examples:
Positive and negative zeroes are distinct.
```assert(cmp(-0.0, +0.0) < 0);
assert(cmp(+0.0, -0.0) > 0);
```
Examples:
Depending on the sign, NANs go to either end of the spectrum.
```assert(cmp(-double.nan, -double.infinity) < 0);
assert(cmp(double.infinity, double.nan) < 0);
assert(cmp(-double.nan, double.nan) < 0);
```
Examples:
NANs of the same sign are ordered by the payload.
```assert(cmp(NaN(10), NaN(20)) < 0);
assert(cmp(-NaN(20), -NaN(10)) < 0);
```