我知道你不能正常依赖双重或十进制类型值之间的相等,但我想知道0是否是特殊情况.
虽然我可以理解0.00000000000001和0.00000000000002之间的不精确,但0本身似乎很难搞砸,因为它什么都没有.如果你对什么都不精确,那就不再是什么了.
但我对这个话题知之甚少,所以我不能说.
double x = 0.0;
return (x == 0.0) ? true : false;
Run Code Online (Sandbox Code Playgroud)
这会永远回归真实吗?
我有一个简单的C#函数:
public static double Floor(double value, double step)
{
return Math.Floor(value / step) * step;
}
Run Code Online (Sandbox Code Playgroud)
计算较高的数字,低于或等于"值",即"步数"的倍数.但它缺乏精确性,如下面的测试所示:
[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);
}
Run Code Online (Sandbox Code Playgroud)
第一个和第二个断言都可以,但是第三个断言失败,因为结果只等到第6个小数位.这是为什么?有没有办法纠正这个?
更新如果我调试测试我看到值相等,直到第8个小数位而不是第6个,可能是因为Math.Round引入了一些不精确.
注意在我的测试代码中,我写了"F"后缀(显式浮点常量),其中我的意思是"D"(双),所以如果我改变它,我可以有更多的精度.
最近我发现C#的运算符%适用于double.尝试了一些事情,毕竟想出了这个测试:
class Program
{
static void test(double a, double b)
{
if (a % b != a - b * Math.Truncate(a / b))
{
Console.WriteLine(a + ", " + b);
}
}
static void Main(string[] args)
{
test(2.5, 7);
test(-6.7, -3);
test(8.7, 4);
//...
}
}
Run Code Online (Sandbox Code Playgroud)
这个测试中的一切都有效.是否a % b总是等同于a - b*Math.Round(a/b)?如果没有,请向我解释这个运营商是如何运作的.
编辑:回答詹姆斯L,我明白这是一个模数运算符和一切.我很好奇它是如何使用双重的,我理解的整数.
我偶然发现了一个非常奇怪的错误.阅读代码中的注释以查看错误是什么,但实际上变量modulo 1返回1(但它不等于1!).我假设有一个显示问题,浮动非常接近一个但不完全.但是,它应该模数为零.我不能轻易地测试这个案例,因为(最后%1)!= 1.0!当我尝试将相同的数字插入另一个python终端时,一切都表现正常.这是怎么回事?
def r(k,i,p):
first = i*p
last = first + p
steps = int((i+1)*p) - int(i*p)
if steps < 1:
return p
elif steps >= 1:
if k == 0:
return 1 - (first % 1)
elif k == steps:
if i == 189:
print last, 1, type(last), last % 1, last - int(last)
# Prints: 73.0 1 <type 'float'> 1.0 1.0
print last % 1 == 1 # Returns False
if last % 1 == 1.0:
return …Run Code Online (Sandbox Code Playgroud)