这个问题是关于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。 (我后来发现内置的Math.Log10(double)
提供了更加准确的结果。)不应将阈值与
Double.Epsilon
绑定(bind),否则,不应记录该阈值(我在MSDN官方文档中找不到对此的任何提及)? 最佳答案
不。
可表示的 double 并非均匀分布在实数上。接近零,有许多可表示的值。但是,离零越远,可代表的 double 值就越远。对于非常大的数字,即使将1加到 double 值也不会给您带来新的值(value)。
因此,您要寻找的阈值取决于您的人数。这不是一个常数。
关于c# - Math.Floor(double)和Math.Ceiling(double)的异常行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9916808/