这个问题是关于 Math.Floor(double)
和 Math.Ceiling(double)
决定给你上一个或下一个整数值的阈值。我很不安地发现阈值似乎与Double.Epsilon
无关,它是可以用double表示的最小值。例如:
double x = 3.0;
Console.WriteLine( Math.Floor( x - Double.Epsilon ) ); // expected 2, got 3
Console.WriteLine( Math.Ceiling( x + Double.Epsilon) ); // expected 4, got 3
即使将 Double.Epsilon
乘以一个合理的位也没有成功:
Console.WriteLine( Math.Floor( x - Double.Epsilon*1000 ) ); // expected 2, got 3
Console.WriteLine( Math.Ceiling( x + Double.Epsilon*1000) ); // expected 4, got 3
通过一些实验,我能够确定阈值在 2.2E-16 左右,这个值很小,但比 Double.Epsilon
大得多。
出现这个问题的原因是我试图用公式 var digits = Math.Floor( Math.Log( n, 10 ) ) + 1 计算数字中的位数
。此公式不适用于 n=1000
(我完全是偶然发现的),因为 Math.Log( 1000, 10 )
返回一个数字 4.44E-16离其实际值(value)。 (我后来发现内置的 Math.Log10(double)
提供了更准确的结果。)
阈值是否应该绑定(bind)到 Double.Epsilon
或者,如果不是,阈值是否应该被记录(我在官方 MSDN 文档中找不到任何提及) ?
最佳答案
Shouldn't the threshold should be tied to Double.Epsilon
没有。
可表示的 double 并不是均匀分布在实数上。接近于零,有许多可表示的值。但是你离零越远,可表示的 double 就越远。对于非常的大数,即使加 1 到 double 也不会得到新值。
因此,您要寻找的阈值取决于您的数字有多大。它不是常数。
关于c# - Math.Floor(double) 和 Math.Ceiling(double) 的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9916808/