Contains the elementary mathematical functions (powers, roots, and trigonometric functions), and low-level floating-point operations. Mathematical special functions are available in std.mathspecial
.
Category | Members |
---|---|
Constants | E PI PI_2 PI_4 M_1_PI M_2_PI M_2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 |
Classics | abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 |
Trigonometry | sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh expi |
Rounding | ceil floor round lround trunc rint lrint nearbyint rndtol quantize |
Exponentiation & Logarithms | pow exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn |
Modulus | fmod modf remainder |
Floating-point operations | approxEqual feqrel fdim fmax fmin fma nextDown nextUp nextafter NaN getNaNPayload cmp |
Introspection | isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 |
Hardware Control | IeeeFlags FloatingPointControl |
The functionality closely follows the IEEE754-2008 standard for floating-point arithmetic, including the use of camelCase names rather than C99-style lower case names. All of these functions behave correctly when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
e = 2.718281...
log210 = 3.321928...
log2e = 1.442695...
log102 = 0.301029...
log10e = 0.434294...
ln 2 = 0.693147...
ln 10 = 2.302585...
π = 3.141592...
π / 2 = 1.570796...
π / 4 = 0.785398...
1 / π = 0.318309...
2 / π = 0.636619...
2 / √π = 1.128379...
√2 = 1.414213...
√½ = 0.707106...
Calculates the absolute value of a number
Num | (template parameter) type of number |
Num x
| real number value |
assert(isIdentical(abs(-0.0L), 0.0L)); assert(isNaN(abs(real.nan))); writeln(abs(-real.infinity)); // real.infinity writeln(abs(-56)); // 56 writeln(abs(2321312L)); // 2321312L
Returns cosine of x. x is in radians.
x | cos(x) | invalid? |
---|---|---|
NAN | NAN | yes |
±∞ | NAN | yes |
writeln(cos(0.0)); // 1.0 assert(cos(1.0).approxEqual(0.540)); assert(cos(3.0).approxEqual(-0.989));
Returns sine of x. x is in radians.
x | sin(x) | invalid? |
---|---|---|
NAN | NAN | yes |
±0.0 | ±0.0 | no |
±∞ | NAN | yes |
real x
| angle in radians (not degrees) |
import std.math : sin, PI; import std.stdio : writefln; void someFunc() { real x = 30.0; auto result = sin(x * (PI / 180)); // convert degrees to radians writefln("The sine of %s degrees is %s", x, result); }
Returns tangent of x. x is in radians.
x | tan(x) | invalid? |
---|---|---|
NAN | NAN | yes |
±0.0 | ±0.0 | no |
±∞ | NAN | yes |
assert(isIdentical(tan(0.0), 0.0)); assert(tan(PI).approxEqual(0)); assert(tan(PI / 3).approxEqual(sqrt(3.0)));
Calculates the arc cosine of x, returning a value ranging from 0 to π.
x | acos(x) | invalid? |
---|---|---|
>1.0 | NAN | yes |
<-1.0 | NAN | yes |
NAN | NAN | yes |
assert(acos(0.0).approxEqual(1.570)); assert(acos(0.5).approxEqual(std.math.PI / 3)); assert(acos(PI).isNaN);
Calculates the arc sine of x, returning a value ranging from -π/2 to π/2.
x | asin(x) | invalid? |
---|---|---|
±0.0 | ±0.0 | no |
>1.0 | NAN | yes |
<-1.0 | NAN | yes |
assert(isIdentical(asin(0.0), 0.0)); assert(asin(0.5).approxEqual(PI / 6)); assert(asin(PI).isNaN);
Calculates the arc tangent of x, returning a value ranging from -π/2 to π/2.
x | atan(x) | invalid? |
---|---|---|
±0.0 | ±0.0 | no |
±∞ | NAN | yes |
assert(isIdentical(atan(0.0), 0.0)); assert(atan(sqrt(3.0)).approxEqual(PI / 3));
Calculates the arc tangent of y / x, returning a value ranging from -π to π.
y | x | atan(y, x) |
---|---|---|
NAN | anything | NAN |
anything | NAN | NAN |
±0.0 | >0.0 | ±0.0 |
±0.0 | +0.0 | ±0.0 |
±0.0 | <0.0 | ±π |
±0.0 | -0.0 | ±π |
>0.0 | ±0.0 | π/2 |
<0.0 | ±0.0 | -π/2 |
>0.0 | ∞ | ±0.0 |
±∞ | anything | ±π/2 |
>0.0 | -∞ | ±π |
±∞ | ∞ | ±π/4 |
±∞ | -∞ | ±3π/4 |
assert(atan2(1.0, sqrt(3.0)).approxEqual(PI / 6));
Calculates the hyperbolic cosine of x.
x | cosh(x) | invalid? |
---|---|---|
±∞ | ±0.0 | no |
writeln(cosh(0.0)); // 1.0 assert(cosh(1.0).approxEqual((E + 1.0 / E) / 2));
Calculates the hyperbolic sine of x.
x | sinh(x) | invalid? |
---|---|---|
±0.0 | ±0.0 | no |
±∞ | ±∞ | no |
assert(isIdentical(sinh(0.0), 0.0)); assert(sinh(1.0).approxEqual((E - 1.0 / E) / 2));
Calculates the hyperbolic tangent of x.
x | tanh(x) | invalid? |
---|---|---|
±0.0 | ±0.0 | no |
±∞ | ±1.0 | no |
assert(isIdentical(tanh(0.0), 0.0)); assert(tanh(1.0).approxEqual(sinh(1.0) / cosh(1.0)));
Calculates the inverse hyperbolic cosine of x.
Mathematically, acosh(x) = log(x + sqrt( x*x - 1))
Domain X | Range Y |
---|---|
1..∞ | 0..∞ |
x | acosh(x) |
---|---|
NAN | NAN |
<1 | NAN |
1 | 0 |
+∞ | +∞ |
assert(isNaN(acosh(0.9))); assert(isNaN(acosh(real.nan))); assert(isIdentical(acosh(1.0), 0.0)); writeln(acosh(real.infinity)); // real.infinity assert(isNaN(acosh(0.5)));
Calculates the inverse hyperbolic sine of x.
Mathematically,
asinh(x) = log( x + sqrt( x*x + 1 )) // if x >= +0 asinh(x) = -log(-x + sqrt( x*x + 1 )) // if x <= -0
x | asinh(x) |
---|---|
NAN | NAN |
±0 | ±0 |
±∞ | ±∞ |
assert(isIdentical(asinh(0.0), 0.0)); assert(isIdentical(asinh(-0.0), -0.0)); writeln(asinh(real.infinity)); // real.infinity writeln(asinh(-real.infinity)); // -real.infinity assert(isNaN(asinh(real.nan)));
Calculates the inverse hyperbolic tangent of x, returning a value from ranging from -1 to 1.
Mathematically, atanh(x) = log( (1+x)/(1-x) ) / 2
Domain X | Range Y |
---|---|
-∞..∞ | -1 .. 1 |
x | acosh(x) |
---|---|
NAN | NAN |
±0 | ±0 |
-∞ | -0 |
assert(isIdentical(atanh(0.0), 0.0)); assert(isIdentical(atanh(-0.0),-0.0)); assert(isNaN(atanh(real.nan))); assert(isNaN(atanh(-real.infinity))); writeln(atanh(0.0)); // 0
Returns x rounded to a long value using the current rounding mode. If the integer value of x is greater than long.max, the result is indeterminate.
writeln(rndtol(1.0)); // 1L writeln(rndtol(1.2)); // 1L writeln(rndtol(1.7)); // 2L writeln(rndtol(1.0001)); // 1L
Deprecated. Please use round
instead.
Returns x
rounded to a long
value using the FE_TONEAREST
rounding mode. If the integer value of x
is greater than long.max
, the result is indeterminate.
Only works with the Digital Mars C Runtime.
real x
| the number to round |
x
rounded to an integer valueversion (CRuntime_DigitalMars) { assert(rndtonl(1.0) is -real.nan); assert(rndtonl(1.2) is -real.nan); assert(rndtonl(1.7) is -real.nan); assert(rndtonl(1.0001) is -real.nan); }
Compute square root of x.
x | sqrt(x) | invalid? |
---|---|---|
-0.0 | -0.0 | no |
<0.0 | NAN | yes |
+∞ | +∞ | no |
assert(sqrt(2.0).feqrel(1.4142) > 16); assert(sqrt(9.0).feqrel(3.0) > 16); assert(isNaN(sqrt(-1.0f))); assert(isNaN(sqrt(-1.0))); assert(isNaN(sqrt(-1.0L)));
Calculates ex.
x | ex |
---|---|
+∞ | +∞ |
-∞ | +0.0 |
NAN | NAN |
writeln(exp(0.0)); // 1.0 assert(exp(3.0).feqrel(E * E * E) > 16);
Calculates the value of the natural logarithm base (e) raised to the power of x, minus 1.
For very small x, expm1(x) is more accurate than exp(x)-1.
x | ex-1 |
---|---|
±0.0 | ±0.0 |
+∞ | +∞ |
-∞ | -1.0 |
NAN | NAN |
assert(isIdentical(expm1(0.0), 0.0)); assert(expm1(1.0).feqrel(1.71828) > 16); assert(expm1(2.0).feqrel(6.3890) > 16);
Calculates 2x.
x | exp2(x) |
---|---|
+∞ | +∞ |
-∞ | +0.0 |
NAN | NAN |
assert(isIdentical(exp2(0.0), 1.0)); assert(exp2(2.0).feqrel(4.0) > 16); assert(exp2(8.0).feqrel(256.0) > 16);
Separate floating point value into significand and exponent.
value | returns | exp |
---|---|---|
±0.0 | ±0.0 | 0 |
+∞ | +∞ | int.max |
-∞ | -∞ | int.min |
±NAN | ±NAN | int.min |
int exp; real mantissa = frexp(123.456L, exp); assert(approxEqual(mantissa * pow(2.0L, cast(real) exp), 123.456L)); assert(frexp(-real.nan, exp) && exp == int.min); assert(frexp(real.nan, exp) && exp == int.min); assert(frexp(-real.infinity, exp) == -real.infinity && exp == int.min); assert(frexp(real.infinity, exp) == real.infinity && exp == int.max); assert(frexp(-0.0, exp) == -0.0 && exp == 0); assert(frexp(0.0, exp) == 0.0 && exp == 0);
Extracts the exponent of x as a signed integral value.
If x is not a special value, the result is the same as cast(int) logb(x)
.
x | ilogb(x) | Range error? |
---|---|---|
0 | FP_ILOGB0 | yes |
±∞ | int.max | no |
NAN | FP_ILOGBNAN | no |
writeln(ilogb(1)); // 0 writeln(ilogb(3)); // 1 writeln(ilogb(3.0)); // 1 writeln(ilogb(100_000_000)); // 26 writeln(ilogb(0)); // FP_ILOGB0 writeln(ilogb(0.0)); // FP_ILOGB0 writeln(ilogb(double.nan)); // FP_ILOGBNAN writeln(ilogb(double.infinity)); // int.max
Special return values of ilogb
.
writeln(ilogb(0)); // FP_ILOGB0 writeln(ilogb(0.0)); // FP_ILOGB0 writeln(ilogb(double.nan)); // FP_ILOGBNAN
Compute n * 2exp
import std.meta : AliasSeq; static foreach (T; AliasSeq!(float, double, real)) {{ T r; r = ldexp(3.0L, 3); writeln(r); // 24 r = ldexp(cast(T) 3.0, cast(int) 3); writeln(r); // 24 T n = 3.0; int exp = 3; r = ldexp(n, exp); writeln(r); // 24 }}
Calculate the natural logarithm of x.
x | log(x) | divide by 0? | invalid? |
---|---|---|---|
±0.0 | -∞ | yes | no |
<0.0 | NAN | no | yes |
+∞ | +∞ | no | no |
assert(feqrel(log(E), 1) >= real.mant_dig - 1);
Calculate the base-10 logarithm of x.
x | log10(x) | divide by 0? | invalid? |
---|---|---|---|
±0.0 | -∞ | yes | no |
<0.0 | NAN | no | yes |
+∞ | +∞ | no | no |
assert(fabs(log10(1000) - 3) < .000001);
Calculates the natural logarithm of 1 + x.
For very small x, log1p(x) will be more accurate than log(1 + x).
x | log1p(x) | divide by 0? | invalid? |
---|---|---|---|
±0.0 | ±0.0 | no | no |
-1.0 | -∞ | yes | no |
<-1.0 | -NAN | no | yes |
+∞ | +∞ | no | no |
assert(isIdentical(log1p(0.0), 0.0)); assert(log1p(1.0).feqrel(0.69314) > 16); writeln(log1p(-1.0)); // -real.infinity assert(isNaN(log1p(-2.0))); assert(log1p(real.nan) is real.nan); assert(log1p(-real.nan) is -real.nan); writeln(log1p(real.infinity)); // real.infinity
Calculates the base-2 logarithm of x: log2x
x | log2(x) | divide by 0? | invalid? |
---|---|---|---|
±0.0 | -∞ | yes | no |
<0.0 | NAN | no | yes |
+∞ | +∞ | no | no |
assert(approxEqual(log2(1024.0L), 10));
Extracts the exponent of x as a signed integral value.
If x is subnormal, it is treated as if it were normalized. For a positive, finite x:
1 <= x * FLT_RADIX-logb(x) < FLT_RADIX
x | logb(x) | divide by 0? |
---|---|---|
±∞ | +∞ | no |
±0.0 | -∞ | yes |
writeln(logb(1.0)); // 0 writeln(logb(100.0)); // 6 writeln(logb(0.0)); // -real.infinity writeln(logb(real.infinity)); // real.infinity writeln(logb(-real.infinity)); // real.infinity
Calculates the remainder from the calculation x/y.
x | y | fmod(x, y) | invalid? |
---|---|---|---|
±0.0 | not 0.0 | ±0.0 | no |
±∞ | anything | NAN | yes |
anything | ±0.0 | NAN | yes |
!=±∞ | ±∞ | x | no |
assert(isIdentical(fmod(0.0, 1.0), 0.0)); assert(fmod(5.0, 3.0).feqrel(2.0) > 16); assert(isNaN(fmod(5.0, 0.0)));
Breaks x into an integral part and a fractional part, each of which has the same sign as x. The integral part is stored in i.
x | i (on input) | modf(x, i) | i (on return) |
---|---|---|---|
±∞ | anything | ±0.0 | ±∞ |
real frac; real intpart; frac = modf(3.14159, intpart); assert(intpart.feqrel(3.0) > 16); assert(frac.feqrel(0.14159) > 16);
Efficiently calculates x * 2n.
scalbn handles underflow and overflow in the same fashion as the basic arithmetic operators.
x | scalb(x) |
---|---|
±∞ | ±∞ |
±0.0 | ±0.0 |
writeln(scalbn(-real.infinity, 5)); // -real.infinity
Calculates the cube root of x.
x | cbrt(x) | invalid? |
---|---|---|
±0.0 | ±0.0 | no |
NAN | NAN | yes |
±∞ | ±∞ | no |
assert(cbrt(1.0).feqrel(1.0) > 16); assert(cbrt(27.0).feqrel(3.0) > 16); assert(cbrt(15.625).feqrel(2.5) > 16);
Returns |x|
x | fabs(x) |
---|---|
±0.0 | +0.0 |
±∞ | +∞ |
assert(isIdentical(fabs(0.0), 0.0)); assert(isIdentical(fabs(-0.0), 0.0)); writeln(fabs(-10.0)); // 10.0
Calculates the length of the hypotenuse of a right-angled triangle with sides of length x and y. The hypotenuse is the value of the square root of the sums of the squares of x and y:
sqrt(x2 + y2)
Note that hypot(x, y), hypot(y, x) and hypot(x, -y) are equivalent.
x | y | hypot(x, y) | invalid? |
---|---|---|---|
x | ±0.0 | |x| | no |
±∞ | y | +∞ | no |
±∞ | NAN | +∞ | no |
assert(hypot(1.0, 1.0).feqrel(1.4142) > 16); assert(hypot(3.0, 4.0).feqrel(5.0) > 16); writeln(hypot(real.infinity, 1.0)); // real.infinity writeln(hypot(real.infinity, real.nan)); // real.infinity
Returns the value of x rounded upward to the next integer (toward positive infinity).
writeln(ceil(+123.456L)); // +124 writeln(ceil(-123.456L)); // -123 writeln(ceil(-1.234L)); // -1 writeln(ceil(-0.123L)); // 0 writeln(ceil(0.0L)); // 0 writeln(ceil(+0.123L)); // 1 writeln(ceil(+1.234L)); // 2 writeln(ceil(real.infinity)); // real.infinity assert(isNaN(ceil(real.nan))); assert(isNaN(ceil(real.init)));
Returns the value of x rounded downward to the next integer (toward negative infinity).
writeln(floor(+123.456L)); // +123 writeln(floor(-123.456L)); // -124 writeln(floor(+123.0L)); // +123 writeln(floor(-124.0L)); // -124 writeln(floor(-1.234L)); // -2 writeln(floor(-0.123L)); // -1 writeln(floor(0.0L)); // 0 writeln(floor(+0.123L)); // 0 writeln(floor(+1.234L)); // 1 writeln(floor(real.infinity)); // real.infinity assert(isNaN(floor(real.nan))); assert(isNaN(floor(real.init)));
Round val
to a multiple of unit
. rfunc
specifies the rounding function to use; by default this is rint
, which uses the current rounding mode.
writeln(12345.6789L.quantize(0.01L)); // 12345.68L writeln(12345.6789L.quantize!floor(0.01L)); // 12345.67L writeln(12345.6789L.quantize(22.0L)); // 12342.0L
writeln(12345.6789L.quantize(0)); // 12345.6789L assert(12345.6789L.quantize(real.infinity).isNaN); assert(12345.6789L.quantize(real.nan).isNaN); writeln(real.infinity.quantize(0.01L)); // real.infinity assert(real.infinity.quantize(real.nan).isNaN); assert(real.nan.quantize(0.01L).isNaN); assert(real.nan.quantize(real.infinity).isNaN); assert(real.nan.quantize(real.nan).isNaN);
Round val
to a multiple of pow(base, exp)
. rfunc
specifies the rounding function to use; by default this is rint
, which uses the current rounding mode.
writeln(12345.6789L.quantize!10(-2)); // 12345.68L writeln(12345.6789L.quantize!(10, -2)); // 12345.68L writeln(12345.6789L.quantize!(10, floor)(-2)); // 12345.67L writeln(12345.6789L.quantize!(10, -2, floor)); // 12345.67L writeln(12345.6789L.quantize!22(1)); // 12342.0L writeln(12345.6789L.quantize!22); // 12342.0L
Rounds x to the nearest integer value, using the current rounding mode.
Unlike the rint functions, nearbyint does not raise the FE_INEXACT exception.
version (CRuntime_Microsoft) {} else { writeln(nearbyint(0.4)); // 0 writeln(nearbyint(0.5)); // 0 writeln(nearbyint(0.6)); // 1 writeln(nearbyint(100.0)); // 100 assert(isNaN(nearbyint(real.nan))); writeln(nearbyint(real.infinity)); // real.infinity writeln(nearbyint(-real.infinity)); // -real.infinity }
Rounds x to the nearest integer value, using the current rounding mode.
If the return value is not equal to x, the FE_INEXACT exception is raised.
nearbyint
performs the same operation, but does not set the FE_INEXACT exception.
version (InlineAsm_X86_Any) { resetIeeeFlags(); writeln(rint(0.4)); // 0 assert(ieeeFlags.inexact); writeln(rint(0.5)); // 0 writeln(rint(0.6)); // 1 writeln(rint(100.0)); // 100 assert(isNaN(rint(real.nan))); writeln(rint(real.infinity)); // real.infinity writeln(rint(-real.infinity)); // -real.infinity }
Rounds x to the nearest integer value, using the current rounding mode.
This is generally the fastest method to convert a floating-point number to an integer. Note that the results from this function depend on the rounding mode, if the fractional part of x is exactly 0.5. If using the default rounding mode (ties round to even integers) lrint(4.5) == 4, lrint(5.5)==6.
writeln(lrint(4.5)); // 4 writeln(lrint(5.5)); // 6 writeln(lrint(-4.5)); // -4 writeln(lrint(-5.5)); // -6 writeln(lrint(int.max - 0.5)); // 2147483646L writeln(lrint(int.max + 0.5)); // 2147483648L writeln(lrint(int.min - 0.5)); // -2147483648L writeln(lrint(int.min + 0.5)); // -2147483648L
Return the value of x rounded to the nearest integer. If the fractional part of x is exactly 0.5, the return value is rounded away from zero.
real
.writeln(round(4.5)); // 5 writeln(round(5.4)); // 5 writeln(round(-4.5)); // -5 writeln(round(-5.1)); // -5
Return the value of x rounded to the nearest integer.
If the fractional part of x is exactly 0.5, the return value is rounded away from zero.
This function is Posix-Only.
version (Posix) { writeln(lround(0.49)); // 0 writeln(lround(0.5)); // 1 writeln(lround(1.5)); // 2 }
Returns the integer portion of x, dropping the fractional portion. This is also known as "chop" rounding. pure
on all platforms.
writeln(trunc(0.01)); // 0 writeln(trunc(0.49)); // 0 writeln(trunc(0.5)); // 0 writeln(trunc(1.5)); // 1
Calculate the remainder x REM y, following IEC 60559.
REM is the value of x - y * n, where n is the integer nearest the exact value of x / y. If |n - x / y| == 0.5, n is even. If the result is zero, it has the same sign as x. Otherwise, the sign of the result is the sign of x / y. Precision mode has no effect on the remainder functions.
remquo returns n
in the parameter n
.
x | y | remainder(x, y) | n | invalid? |
---|---|---|---|---|
±0.0 | not 0.0 | ±0.0 | 0.0 | no |
±∞ | anything | -NAN | ? | yes |
anything | ±0.0 | ±NAN | ? | yes |
!= ±∞ | ±∞ | x | ? | no |
remquo
and remainder
not supported on Windows. version (Posix) { assert(remainder(5.1, 3.0).feqrel(-0.9) > 16); assert(remainder(-5.1, 3.0).feqrel(0.9) > 16); writeln(remainder(0.0, 3.0)); // 0.0 assert(isNaN(remainder(1.0, 0.0))); assert(isNaN(remainder(-1.0, 0.0))); }
version (Posix) { int n; assert(remquo(5.1, 3.0, n).feqrel(-0.9) > 16 && n == 2); assert(remquo(-5.1, 3.0, n).feqrel(0.9) > 16 && n == -2); assert(remquo(0.0, 3.0, n) == 0.0 && n == 0); }
IEEE exception status flags ('sticky bits')
These flags indicate that an exceptional floating-point condition has occurred. They indicate that a NaN or an infinity has been generated, that a result is inexact, or that a signalling NaN has been encountered. If floating-point exceptions are enabled (unmasked), a hardware exception will be generated instead of setting these flags.
version (InlineAsm_X86_Any) { static void func() { int a = 10 * 10; } real a = 3.5; // Set all the flags to zero resetIeeeFlags(); assert(!ieeeFlags.divByZero); // Perform a division by zero. a /= 0.0L; writeln(a); // real.infinity assert(ieeeFlags.divByZero); // Create a NaN a *= 0.0L; assert(ieeeFlags.invalid); assert(isNaN(a)); // Check that calling func() has no effect on the // status flags. IeeeFlags f = ieeeFlags; func(); writeln(ieeeFlags); // f }
The result cannot be represented exactly, so rounding occurred.
x = sin(0.1);
A zero was generated by underflow
x = real.min*real.epsilon/2;
An infinity was generated by overflow
x = real.max*2;
An infinity was generated by division by zero
x = 3/0.0;
A machine NaN was generated.
x = real.infinity * 0.0;
Set all of the floating-point status flags to false.
version (InlineAsm_X86_Any) { resetIeeeFlags(); real a = 3.5; a /= 0.0L; writeln(a); // real.infinity assert(ieeeFlags.divByZero); resetIeeeFlags(); assert(!ieeeFlags.divByZero); }
version (InlineAsm_X86_Any) { resetIeeeFlags(); real a = 3.5; a /= 0.0L; writeln(a); // real.infinity assert(ieeeFlags.divByZero); a *= 0.0L; assert(isNaN(a)); assert(ieeeFlags.invalid); }
Control the Floating point hardware
Change the IEEE754 floating-point rounding mode and the floating-point hardware exceptions.
By default, the rounding mode is roundToNearest and all hardware exceptions are disabled. For most applications, debugging is easier if the division by zero, overflow, and invalid operation exceptions are enabled. These three are combined into a severeExceptions value for convenience. Note in particular that if invalidException is enabled, a hardware trap will be generated whenever an uninitialized floating-point variable is used.
All changes are temporary. The previous state is restored at the end of the scope.
{ FloatingPointControl fpctrl; // Enable hardware exceptions for division by zero, overflow to infinity, // invalid operations, and uninitialized floating-point variables. fpctrl.enableExceptions(FloatingPointControl.severeExceptions); // This will generate a hardware exception, if x is a // default-initialized floating point variable: real x; // Add `= 0` or even `= real.nan` to not throw the exception. real y = x * 3.0; // The exception is only thrown for default-uninitialized NaN-s. // NaN-s with other payload are valid: real z = y * real.nan; // ok // The set hardware exceptions and rounding modes will be disabled when // leaving this scope. }
version (InlineAsm_X86_Any) { FloatingPointControl fpctrl; fpctrl.rounding = FloatingPointControl.roundDown; writeln(lrint(1.5)); // 1.0 fpctrl.rounding = FloatingPointControl.roundUp; writeln(lrint(1.4)); // 2.0 fpctrl.rounding = FloatingPointControl.roundToNearest; writeln(lrint(1.5)); // 2.0 }
IEEE rounding modes. The default mode is roundToNearest.
roundingMask = A mask of all rounding modes.
Change the floating-point hardware rounding mode
Changing the rounding mode in the middle of a function can interfere with optimizations of floating point expressions, as the optimizer assumes that the rounding mode does not change. It is best to change the rounding mode only at the beginning of the function, and keep it until the function returns. It is also best to add the line:
pragma(inline, false);as the first line of the function so it will not get inlined.
RoundingMode newMode
| the new rounding mode |
IEEE hardware exceptions. By default, all exceptions are masked (disabled).
severeExceptions = The overflow, division by zero, and invalid exceptions.
Enable (unmask) specific hardware exceptions. Multiple exceptions may be ORed together.
Disable (mask) specific hardware exceptions. Multiple exceptions may be ORed together.
Determines if x is NaN.
X x
| a floating point number. |
true
if x is Nan.assert( isNaN(float.init)); assert( isNaN(-double.init)); assert( isNaN(real.nan)); assert( isNaN(-real.nan)); assert(!isNaN(cast(float) 53.6)); assert(!isNaN(cast(real)-53.6));
Determines if x is finite.
X x
| a floating point number. |
true
if x is finite.assert( isFinite(1.23f)); assert( isFinite(float.max)); assert( isFinite(float.min_normal)); assert(!isFinite(float.nan)); assert(!isFinite(float.infinity));
Determines if x is normalized.
A normalized number must not be zero, subnormal, infinite nor NAN.
X x
| a floating point number. |
true
if x is normalized.float f = 3; double d = 500; real e = 10e+48; assert(isNormal(f)); assert(isNormal(d)); assert(isNormal(e)); f = d = e = 0; assert(!isNormal(f)); assert(!isNormal(d)); assert(!isNormal(e)); assert(!isNormal(real.infinity)); assert(isNormal(-real.max)); assert(!isNormal(real.min_normal/4));
Determines if x is subnormal.
Subnormals (also known as "denormal number"), have a 0 exponent and a 0 most significant mantissa bit.
X x
| a floating point number. |
true
if x is a denormal number.import std.meta : AliasSeq; static foreach (T; AliasSeq!(float, double, real)) {{ T f; for (f = 1.0; !isSubnormal(f); f /= 2) assert(f != 0); }}
Determines if x is ±∞.
X x
| a floating point number. |
true
if x is ±∞.assert(!isInfinity(float.init)); assert(!isInfinity(-float.init)); assert(!isInfinity(float.nan)); assert(!isInfinity(-float.nan)); assert(isInfinity(float.infinity)); assert(isInfinity(-float.infinity)); assert(isInfinity(-1.0f / 0.0f));
Is the binary representation of x identical to y?
Same as ==, except that positive and negative zero are not identical, and two NANs are identical if they have the same 'payload'.
assert( isIdentical(0.0, 0.0)); assert( isIdentical(1.0, 1.0)); assert( isIdentical(real.infinity, real.infinity)); assert( isIdentical(-real.infinity, -real.infinity)); assert(!isIdentical(0.0, -0.0)); assert(!isIdentical(real.nan, -real.nan)); assert(!isIdentical(real.infinity, -real.infinity));
Return 1 if sign bit of e is set, 0 if not.
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));
R to
| the numeric value to use |
X from
| the sign value to use |
writeln(copysign(1.0, 1.0)); // 1.0 writeln(copysign(1.0, -0.0)); // -1.0 writeln(copysign(1UL, -1.0)); // -1.0 writeln(copysign(-1.0, -1.0)); // -1.0 writeln(copysign(real.infinity, -1.0)); // -real.infinity assert(copysign(real.nan, 1.0) is real.nan); assert(copysign(-real.nan, 1.0) is real.nan); assert(copysign(real.nan, -1.0) is -real.nan);
Returns -1
if x < 0
, x
if x == 0
, 1
if x > 0
, and NAN if x==NAN.
writeln(sgn(168.1234)); // 1 writeln(sgn(-168.1234)); // -1 writeln(sgn(0.0)); // 0 writeln(sgn(-0.0)); // 0
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.
real a = NaN(1_000_000); assert(isNaN(a)); writeln(getNaNPayload(a)); // 1_000_000
Extract an integral payload from a NAN.
real a = NaN(1_000_000); assert(isNaN(a)); writeln(getNaNPayload(a)); // 1_000_000
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.
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);
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.
x | nextDown(x) |
---|---|
∞ | real.max |
±0.0 | -real.min_normal*real.epsilon |
-real.max | -∞ |
-∞ | -∞ |
NAN | NAN |
writeln(nextDown(1.0 + real.epsilon)); // 1.0
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.
float a = 1; assert(is(typeof(nextafter(a, a)) == float)); assert(nextafter(a, a.infinity) > a); double b = 2; assert(is(typeof(nextafter(b, b)) == double)); assert(nextafter(b, b.infinity) > b); real c = 3; assert(is(typeof(nextafter(c, c)) == real)); assert(nextafter(c, c.infinity) > c);
Returns the positive difference between x and y.
Equivalent to fmax(x-y, 0)
.
x, y | fdim(x, y) |
---|---|
x > y | x - y |
x <= y | +0.0 |
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)));
Returns the larger of x and y.
If one of the arguments is a NaN, the other is returned.
writeln(fmax(0.0, 2.0)); // 2.0 writeln(fmax(-2.0, 0.0)); // 0.0 writeln(fmax(real.infinity, 2.0)); // real.infinity writeln(fmax(real.nan, 2.0)); // 2.0 writeln(fmax(2.0, real.nan)); // 2.0
Returns the smaller of x and y.
If one of the arguments is a NaN, the other is returned.
writeln(fmin(0.0, 2.0)); // 0.0 writeln(fmin(-2.0, 0.0)); // -2.0 writeln(fmin(real.infinity, 2.0)); // 2.0 writeln(fmin(real.nan, 2.0)); // 2.0 writeln(fmin(2.0, real.nan)); // 2.0
Returns (x * y) + z, rounding only once according to the current rounding mode.
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);
Compute the value of x n, where n is an integer
writeln(pow(2.0, 5)); // 32.0 assert(pow(1.5, 9).feqrel(38.4433) > 16); assert(pow(real.nan, 2) is real.nan); writeln(pow(real.infinity, 2)); // real.infinity
Compute the value of an integer x, raised to the power of a positive integer n.
If both x and n are 0, the result is 1. If n is negative, an integer divide error will occur at runtime, regardless of the value of x.
immutable int one = 1; immutable byte two = 2; immutable ubyte three = 3; immutable short four = 4; immutable long ten = 10; writeln(pow(two, three)); // 8 writeln(pow(two, ten)); // 1024 writeln(pow(one, ten)); // 1 writeln(pow(ten, four)); // 10_000 writeln(pow(four, 10)); // 1_048_576 writeln(pow(three, four)); // 81
Computes integer to floating point powers.
writeln(pow(2, 5.0)); // 32.0 writeln(pow(7, 3.0)); // 343.0 assert(pow(2, real.nan) is real.nan); writeln(pow(2, real.infinity)); // real.infinity
Calculates xy.
x | y | pow(x, y) | div 0 | invalid? |
---|---|---|---|---|
anything | ±0.0 | 1.0 | no | no |
|x| > 1 | +∞ | +∞ | no | no |
|x| < 1 | +∞ | +0.0 | no | no |
|x| > 1 | -∞ | +0.0 | no | no |
|x| < 1 | -∞ | +∞ | no | no |
+∞ | > 0.0 | +∞ | no | no |
+∞ | < 0.0 | +0.0 | no | no |
-∞ | odd integer > 0.0 | -∞ | no | no |
-∞ | > 0.0, not odd integer | +∞ | no | no |
-∞ | odd integer < 0.0 | -0.0 | no | no |
-∞ | < 0.0, not odd integer | +0.0 | no | no |
±1.0 | ±∞ | -NAN | no | yes |
< 0.0 | finite, nonintegral | NAN | no | yes |
±0.0 | odd integer < 0.0 | ±∞ | yes | no |
±0.0 | < 0.0, not odd integer | +∞ | yes | no |
±0.0 | odd integer > 0.0 | ±0.0 | no | no |
±0.0 | > 0.0, not odd integer | +0.0 | no | no |
writeln(pow(1.0, 2.0)); // 1.0 writeln(pow(0.0, 0.0)); // 1.0 assert(pow(1.5, 10.0).feqrel(57.665) > 16); // special values writeln(pow(1.5, real.infinity)); // real.infinity writeln(pow(0.5, real.infinity)); // 0.0 writeln(pow(1.5, -real.infinity)); // 0.0 writeln(pow(0.5, -real.infinity)); // real.infinity writeln(pow(real.infinity, 1.0)); // real.infinity writeln(pow(real.infinity, -1.0)); // 0.0 writeln(pow(-real.infinity, 1.0)); // -real.infinity writeln(pow(-real.infinity, 2.0)); // real.infinity writeln(pow(-real.infinity, -1.0)); // -0.0 writeln(pow(-real.infinity, -2.0)); // 0.0 assert(pow(1.0, real.infinity) is -real.nan); writeln(pow(0.0, -1.0)); // real.infinity writeln(pow(real.nan, 0.0)); // 1.0
Computes the value of a positive integer x
, raised to the power n
, modulo m
.
F x
| base |
G n
| exponent |
H m
| modulus |
x
to the power n
, modulo m
. The return type is the largest of x
's and m
's type. The function requires that all values have unsigned types.writeln(powmod(1U, 10U, 3U)); // 1 writeln(powmod(3U, 2U, 6U)); // 3 writeln(powmod(5U, 5U, 15U)); // 5 writeln(powmod(2U, 3U, 5U)); // 3 writeln(powmod(2U, 4U, 5U)); // 1 writeln(powmod(2U, 5U, 5U)); // 2
To what precision is x equal to y?
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)); // 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);
Evaluate polynomial A(x) = a0 + a1x + a2x2 + a3x3; ...
Uses Horner's rule A(x) = a0 + x(a1 + x(a2 + x(a3 + ...)))
T1 x
| the value to evaluate. |
T2[] A
| array of coefficients a0, a1, etc. |
real x = 3.1; static real[] pp = [56.1, 32.7, 6]; writeln(poly(x, pp)); // (56.1L + (32.7L + 6.0L * x) * x)
Computes whether two values are approximately equal, admitting a maximum relative difference, and a maximum absolute difference.
T lhs
| First item to compare. |
U rhs
| Second item to compare. |
V maxRelDiff
| Maximum allowable difference relative to rhs . Defaults to 1e-2 . |
V maxAbsDiff
| Maximum absolute difference. Defaults to 1e-5 . |
true
if the two items are approximately equal under either criterium. 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. feqrel
to get the number of equal bits in the mantissa.assert(approxEqual(1.0, 1.0099)); assert(!approxEqual(1.0, 1.011)); float[] arr1 = [ 1.0, 2.0, 3.0 ]; double[] arr2 = [ 1.001, 1.999, 3 ]; assert(approxEqual(arr1, arr2)); real num = real.infinity; assert(num == real.infinity); // Passes. assert(approxEqual(num, real.infinity)); // Fails. num = -real.infinity; assert(num == -real.infinity); // Passes. assert(approxEqual(num, -real.infinity)); // Fails. assert(!approxEqual(3, 0)); assert(approxEqual(3, 3)); assert(approxEqual(3.0, 3)); assert(approxEqual([3, 3, 3], 3.0)); assert(approxEqual([3.0, 3.0, 3.0], 3)); int a = 10; assert(approxEqual(10, a));
Defines a total order on all floating-point numbers.
The order is defined as follows:
x
precedes y
in the order specified above; 0 if x
and y
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);
Gives the next power of two after val
. T
can be any built-in numerical type.
If the operation would lead to an over/underflow, this function will return 0
.
T val
| any number |
val
writeln(nextPow2(2)); // 4 writeln(nextPow2(10)); // 16 writeln(nextPow2(4000)); // 4096 writeln(nextPow2(-2)); // -4 writeln(nextPow2(-10)); // -16 writeln(nextPow2(uint.max)); // 0 writeln(nextPow2(uint.min)); // 0 writeln(nextPow2(size_t.max)); // 0 writeln(nextPow2(size_t.min)); // 0 writeln(nextPow2(int.max)); // 0 writeln(nextPow2(int.min)); // 0 writeln(nextPow2(long.max)); // 0 writeln(nextPow2(long.min)); // 0
writeln(nextPow2(2.1)); // 4.0 writeln(nextPow2(-2.0)); // -4.0 writeln(nextPow2(0.25)); // 0.5 writeln(nextPow2(-4.0)); // -8.0 writeln(nextPow2(double.max)); // 0.0 writeln(nextPow2(double.infinity)); // double.infinity
Gives the last power of two before val
. <>> can be any built-in numerical type.
T val
| any number |
val
writeln(truncPow2(3)); // 2 writeln(truncPow2(4)); // 4 writeln(truncPow2(10)); // 8 writeln(truncPow2(4000)); // 2048 writeln(truncPow2(-5)); // -4 writeln(truncPow2(-20)); // -16 writeln(truncPow2(uint.max)); // int.max + 1 writeln(truncPow2(uint.min)); // 0 writeln(truncPow2(ulong.max)); // long.max + 1 writeln(truncPow2(ulong.min)); // 0 writeln(truncPow2(int.max)); // (int.max / 2) + 1 writeln(truncPow2(int.min)); // int.min writeln(truncPow2(long.max)); // (long.max / 2) + 1 writeln(truncPow2(long.min)); // long.min
writeln(truncPow2(2.1)); // 2.0 writeln(truncPow2(7.0)); // 4.0 writeln(truncPow2(-1.9)); // -1.0 writeln(truncPow2(0.24)); // 0.125 writeln(truncPow2(-7.0)); // -4.0 writeln(truncPow2(double.infinity)); // double.infinity
Check whether a number is an integer power of two.
Note that only positive numbers can be integer powers of two. This function always return false
if x
is negative or zero.
X x
| the number to test |
true
if x
is an integer power of two.assert( isPowerOf2(1.0L)); assert( isPowerOf2(2.0L)); assert( isPowerOf2(0.5L)); assert( isPowerOf2(pow(2.0L, 96))); assert( isPowerOf2(pow(2.0L, -77))); assert(!isPowerOf2(-2.0L)); assert(!isPowerOf2(-0.5L)); assert(!isPowerOf2(0.0L)); assert(!isPowerOf2(4.315)); assert(!isPowerOf2(1.0L / 3.0L)); assert(!isPowerOf2(real.nan)); assert(!isPowerOf2(real.infinity));
assert( isPowerOf2(1)); assert( isPowerOf2(2)); assert( isPowerOf2(1uL << 63)); assert(!isPowerOf2(-4)); assert(!isPowerOf2(0)); assert(!isPowerOf2(1337u));
© 1999–2019 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_math.html