Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
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.
License:
Authors:
Walter Bright, Don Clugston,
Conversion of CEPHES math library to D by Iain Buclaw and David Nadlinger
Source std/math/operations.d
- pure nothrow @nogc @trusted real
NaN
(ulongpayload
); - 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)); writeln(getNaNPayload(a)); // 1_000_000
- pure nothrow @nogc @trusted ulong
getNaNPayload
(realx
); - 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)); writeln(getNaNPayload(a)); // 1_000_000
- pure nothrow @nogc @trusted real
nextUp
(realx
);
pure nothrow @nogc @trusted doublenextUp
(doublex
);
pure nothrow @nogc @trusted floatnextUp
(floatx
); - 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
(realx
);
pure nothrow @nogc @safe doublenextDown
(doublex
);
pure nothrow @nogc @safe floatnextDown
(floatx
); - 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 Tx
, const Ty
); - 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
(realx
, realy
); - 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 Fx
, const Fy
)
if (__traits(isFloating, F)); - Returns the larger of
x
andy
.If one of the arguments is a NaN, the other is returned.See Also: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 Fx
, const Fy
)
if (__traits(isFloating, F)); - Returns the smaller of
x
andy
.If one of the arguments is a NaN, the other is returned.See Also: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
(realx
, realy
, realz
); - 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 Xx
, const Xy
)
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)(Tvalue
, Ureference
, VmaxRelDiff
= 0.01, VmaxAbsDiff
= 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 ifvalue
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
returns true if and only if the ranges have the same number of elements and ifapproxEqual
evaluates to true for each pair of elements.See Also:Use feqrel to get the number of equal bits in the mantissa. - bool
isClose
(T, U, V = CommonType!(FloatingPointBaseType!T, FloatingPointBaseType!U))(Tlhs
, Urhs
, VmaxRelDiff
= CommonDefaultFor!(T, U), VmaxAbsDiff
= 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
andrhs
: 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 callingisClose
on each element of the ranged item against the single item. If both items are ranges, thenisClose
returns true if and only if the ranges have the same number of elements and ifisClose
evaluates to true for each pair of elements.See Also: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 ifx
precedesy
in the order specified above; 0 ifx
andy
are identical, and positive value otherwise.See Also:Standards:Conforms to IEEE 754-2008Examples: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);
Copyright © 1999-2024 by the D Language Foundation | Page generated by
Ddoc on Thu Nov 21 01:45:32 2024