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.

# mir.math.ieee

Base floating point routines.
Authors:
Walter Bright, Don Clugston, Ilya Yaroshenko
pure nothrow @nogc @trusted bool `signbit`(T)(const T `x`);
Return true if sign bit of e is set, false if not.
Examples:
```assert(!signbit(float.nan));
assert(signbit(-float.nan));
assert(!signbit(168.1234f));
assert(signbit(-168.1234f));
assert(!signbit(0.0f));
assert(signbit(-0.0f));
assert(signbit(-float.max));
assert(!signbit(float.max));

assert(!signbit(double.nan));
assert(signbit(-double.nan));
assert(!signbit(168.1234));
assert(signbit(-168.1234));
assert(!signbit(0.0));
assert(signbit(-0.0));
assert(signbit(-double.max));
assert(!signbit(double.max));

assert(!signbit(real.nan));
assert(signbit(-real.nan));
assert(!signbit(168.1234L));
assert(signbit(-168.1234L));
assert(!signbit(0.0L));
assert(signbit(-0.0L));
assert(signbit(-real.max));
assert(!signbit(real.max));
```
pure nothrow @nogc @trusted int `feqrel`(T)(const T `x`, const T `y`)
if (isFloatingPoint!T);
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:
```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);
```
enum `RealFormat`: int;
`ieeeHalf`
`ieeeSingle`
`ieeeDouble`
`ieeeExtended`
x87 80-bit real
`ieeeExtended53`
x87 real rounded to precision of double.
`ibmExtended`
IBM 128-bit extended
`ieeeQuadruple`
pure nothrow @nogc @trusted T `nextUp`(T)(const T `x`)
if (isFloatingPoint!T);
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 T `nextDown`(T)(const T `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:
```assert( nextDown(1.0 + real.epsilon) == 1.0);
```
pure nothrow @nogc @trusted T `ieeeMean`(T)(const T `xx`, const T `yy`);
Return the value that lies halfway between x and y on the IEEE number line.
Formally, the result is the arithmetic mean of the binary significands of x and y, multiplied by the geometric mean of the binary exponents of x and y. x and y must not be NaN.

Note this function is useful for ensuring O(log n) behaviour in algorithms involving a 'binary chop'.

Parameters:
 T `xx` x value T `yy` y value Special cases: If x and y not null and have opposite sign bits, then copysign(T(0), y) is returned. If x and y are within a factor of 2 and have the same sign, (ie, feqrel(x, y) > 0), the return value is the arithmetic mean (x + y) / 2. If x and y are even powers of 2 and have the same sign, the return value is the geometric mean, ieeeMean(x, y) = sgn(x) * sqrt(fabs(x * y)).
pure nothrow @nogc @trusted T `frexp`(T)(const T `value`, ref int `exp`)
if (isFloatingPoint!T);
Separate floating point value into significand and exponent.
Returns:
Calculate and return x and exp such that value =x*2exp and .5 <= |x| < 1.0
x has same sign as value.
Special Values
value returns exp
±0.0 ±0.0 0
+∞ +∞ unchenged
-∞ -∞ unchenged
±NAN ±NAN unchenged
Examples:
```import mir.math.common: pow, approxEqual;
alias isNaN = x => x != x;
int exp;
real mantissa = frexp(123.456L, exp);

assert(approxEqual(mantissa * pow(2.0L, cast(real) exp), 123.456L));

// special cases, zero
assert(frexp(-0.0, exp) == -0.0 && exp == 0);
assert(frexp(0.0, exp) == 0.0 && exp == 0);

// special cases, NaNs and INFs
exp = 1234; // random number
assert(isNaN(frexp(-real.nan, exp)) && exp == 1234);
assert(isNaN(frexp(real.nan, exp)) && exp == 1234);
assert(frexp(-real.infinity, exp) == -real.infinity && exp == 1234);
assert(frexp(real.infinity, exp) == real.infinity && exp == 1234);
```
pure nothrow @nogc @trusted T `ldexp`(T)(const T `n`, int `exp`)
if (isFloatingPoint!T);
Returns:
n * 2exp
```import std.meta : AliasSeq;