英語版
このページの英語版を見る

std.math.operations

これは std.math.
浮動小数点数を扱うためのいくつかの関数が含まれている。
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);
静かなNANを作成し、ペイロード内に整数を格納する。
浮動小数点数の場合、可能な最大のペイロードは 0x3F_FFFF である。 倍数の場合、0x3_FFFF_FFFF_FFFFである。 80ビットまたは128ビットの実数の場合、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(real x);
NANから積分ペイロードを取り出す。
Returns:
整数ペイロードをulongとして取り出す。
浮動小数点数の場合、可能な最大のペイロードは 0x3F_FFFF である。 倍数の場合、0x3_FFFF_FFFF_FFFFである。 80ビットまたは128ビットの実数の場合は、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(real x);

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

pure nothrow @nogc @trusted float nextUp(float x);
xの次に大きい浮動小数点値を計算する。
実数として表現可能なxより大きい最小の数を返す; つまり、IEEE数直線上の次の点を返す。
特別な値
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);
xの次に小さい浮動小数点値を計算する。
実数として表現可能なxより小さい最大の数を返す; つまり、IEEE数直線上の前の点を返す。
特別な値
x nextDown(x)
実数値.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);
yの方向にxの次に表現可能な値を計算する。
y > x なら、結果は次に大きい浮動小数点値となる; y < x の場合、結果は次に小さい値となる。 x == yの場合、結果はyとなる。 xまたはyがNaNの場合、結果はNaNである。

備考 この関数は一般的にはあまり役に立たない。 を使う方がよい。

x が有限で、関数結果が無限大の場合、FE_IFXACT および FE_OVERFLOW 例外が発生する。 関数の結果が無限の場合、FE_IFXACT例外とFE_OVERFLOW例外が発生する。例外 FE_INEXACT および FE_UNDERFLOW が発生する。 例外が発生する。 が 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);
x と y の正の差を返す。
と等価である。 fmax(x-y, 0).
Returns:
特別な値
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));
xy.
引数の一方がNaN の場合、もう一方が返される。
See Also:
std.algorithm.comparison.maxの方が速いのは、isNaN テストを行わないからである。
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));
xy.
引数の一方がNaN の場合、もう一方が返される。
See Also:
std.algorithm.comparison.minの方が速いのは、isNaN テストを行わないからである。
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);
(x * y) + z を返す。 を返す。
Bugs:
現在実装されていない - 2回丸める。
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);
xとyはどの程度の精度で等しいか?
Returns:
xとyが等しい仮数ビットの数。 例えば、0x1.F8p+60と0x1.F1p+60は5ビットの精度に等しい。
特殊値
x y feqrel(x, y)
x x real.mant_dig
x >= 2*x 0
x <= x/2 0
ナン 任意の 0
任意 NAN 0
Examples:
writeln(feqrel(2.0, 2.0)); // 53
writeln(feqrel(2.0f, 2.0f)); // 24
writeln(feqrel(2.0, double.nan)); // 0

// feqrel > n * log2(10)かどうかをテストすることによって、
// 数字が互いにn桁以内であることをテストする

// 5桁
assert(feqrel(2.0, 2.00001) > 16);
// 10桁
assert(feqrel(2.0, 2.00000000001) > 33);
bool approxEqual(T, U, V)(T value, U reference, V maxRelDiff = 0.01, V maxAbsDiff = 1e-05);
ある値が基準値とほぼ等しいかどうかを計算する、 最大相対差と最大絶対差を許容する。

警告 このテンプレートは古いとみなされる。このテンプレートは 2.106.0で "phobos"から削除される。代わりに isClose代わりにを達成するために と同様の動作をさせるには approxEqual(a, b)使用する isClose(a, b, 1e-2, 1e-5).0.0と比較する場合は isClose(a, b, 0.0, eps) を使うべきである。eps は0.0からの許容偏差を表す。"

Parameters:
T value 比較する値。
U reference 基準値。
V maxRelDiff に対する最大許容差。 reference. 0.0に設定すると、このチェックは無効になる。デフォルトは1e-2
V maxAbsDiff 最大絶対差。これは主に 値をゼロと比較するときに便利である。0.0に設定すると、このチェックは無効になる。 デフォルトは1e-5 である。
Returns:
true もし valueとほぼ等しい。 referenceである。 に等しい。で十分である。 value で十分である。 で十分である。
一方の項目が範囲であり、もう一方の項目が単一の値である場合、次のようになる。 を呼び出すと、結果は論理的にand-ingとなる。 approxEqualである。 その結果は、範囲項目の各要素を単一項目に対して呼び出す論理和となる。もし 両方の項目が範囲である場合 approxEqualtrue を返す。 を返す。 approxEqualtrue
See Also:
と評価される。 feqrelを使って仮数部の等しいビット数を求める。
bool isClose(T, U, V = CommonType!(FloatingPointBaseType!T, FloatingPointBaseType!U))(T lhs, U rhs, V maxRelDiff = CommonDefaultFor!(T, U), V maxAbsDiff = 0.0);
2つの値がほぼ等しいかどうかを計算する。 最大絶対差を認める。
Parameters:
T lhs 比較する最初の項目
U rhs 比較する2番目の項目
V maxRelDiff 最大許容相対差。 0.0に設定すると、このチェックは無効になる。デフォルトは、"型"に依存する。 lhsrhs:の精度の約半分である。 の精度の小さい方の約半分である。
V maxAbsDiff 最大絶対差。これは主に 値をゼロと比較するときに便利である。0.0に設定するとこのチェックは無効になる。 デフォルトは0.0
Returns:
true をデフォルトとする。 、2つの基準のどちらかを満たせば十分である。 一方の項目が範囲であり、もう一方の項目が単一値である場合、その結果は次のようになる。 を呼び出すと、結果は論理アンドイングとなる。value
isCloseである。 その結果は、範囲項目の各要素を単一項目に対して呼び出す論理和となる。もし 両方の項目が範囲である場合 isClosetrue を返す。 を返す。 isClosetrue
See Also:
を使用する。 feqrelを使って、仮数部の等しいビット数を求める。
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));

// 第3パラメータを明示的に使用し、精度を下げる(または上げる)
assert(isClose(17.123_456_789, 17.123_45, 1e-6));
assert(!isClose(17.123_456_789, 17.123_45, 1e-7));

// ゼロに近い値で比較する場合は第4パラメータを使用する
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));

// 浮動小数点型によってデフォルトの上限が異なる
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);
すべての浮動小数点数の合計順を定義する。
順序は以下のように定義される:
  • のすべての数値は組み込みの比較と同じように並べられる。 にある全ての数値は組み込み比較と同じ順序になる。 -0.0は+0.0より小さい;
  • 符号ビットがセットされている(つまり「負」)場合、NANはどの数値よりも小さい。 符号ビットがセットされていない場合(つまり「正」)、NANは任意の数値より小さい、 NANは任意の数値より大きい;
  • 同じ符号のNANは、ペイロードの順に並ぶ(「負」のものは逆順)。 は逆順)。
Returns:
の場合は負の値である。 xyを指定する; 0である。 xyが同じなら0、そうでなければ正の値となる。
See Also:
Standards:
IEEE 754-2008に準拠する。
Examples:
ほとんどの数字は自然な順序で並んでいる。
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:
正と負のゼロは区別される。
assert(cmp(-0.0, +0.0) < 0);
assert(cmp(+0.0, -0.0) > 0);
Examples:
記号によって、NANはスペクトルの両端に位置する。
assert(cmp(-double.nan, -double.infinity) < 0);
assert(cmp(double.infinity, double.nan) < 0);
assert(cmp(-double.nan, double.nan) < 0);
Examples:
同じ符号のNANは、ペイロード順に並ぶ。
assert(cmp(NaN(10), NaN(20)) < 0);
assert(cmp(-NaN(20), -NaN(10)) < 0);