私は単純なC#関数を持っています:
public static double Floor(double value, double step)
{
return Math.Floor(value / step) * step;
}
これは、「ステップ」の倍数である「値」以下の大きい数を計算します。ただし、次のテストで見られるように、精度が不足しています。
[TestMethod()]
public void FloorTest()
{
int decimals = 6;
double value = 5F;
double step = 2F;
double expected = 4F;
double actual = Class.Floor(value, step);
Assert.AreEqual(expected, actual);
value = -11.5F;
step = 1.1F;
expected = -12.1F;
actual = Class.Floor(value, step);
Assert.AreEqual(Math.Round(expected, decimals),Math.Round(actual, decimals));
Assert.AreEqual(expected, actual);
}
1 番目と 2 番目のアサートは問題ありませんが、3 番目のアサートは失敗します。これは、結果が小数第 6 位までしか変わらないためです。何故ですか?これを修正する方法はありますか?
更新テストをデバッグすると、値が小数点以下 6 桁目ではなく 8 桁目まで等しいことがわかります。これは、おそらく Math.Round によって不正確さが生じるためです。
注:私のテスト コードでは、"D" (倍精度) を意味するところに "F" 接尾辞 (明示的な浮動小数点定数) を書きました。