我知道你不能正常依赖双重或十进制类型值之间的相等,但我想知道0是否是特殊情况。
虽然我可以理解0.00000000000001和0.00000000000002之间的不精确,但是0本身似乎很难搞砸,因为它什么也没有。如果你对什么都不精确,那就不再是什么了。
但我对这个话题知之甚少,所以我不能说。
double x = 0.0;
return (x == 0.0) ? true : false;
这总是会回归吗?
答案 0 :(得分:105)
安全,当且仅当双变量的值精确为true
时,才会期望比较返回0.0
(在原始代码段中为当然,这个案子)。这与==
运算符的语义一致。 a == b
表示“a
等于b
”。
不安全(因为不正确)期望某些计算的结果在double(或更一般地,浮点)算术中为零每当纯数学中相同计算的结果为零时。这是因为当计算出现时,会出现浮点精度误差 - 这个概念在数学中的实数算术中是不存在的。
答案 1 :(得分:47)
如果你需要进行大量的“相等”比较,那么在.NET 3.5中编写一个小帮助函数或扩展方法进行比较可能是一个好主意:
public static bool AlmostEquals(this double double1, double double2, double precision)
{
return (Math.Abs(double1 - double2) <= precision);
}
这可以通过以下方式使用:
double d1 = 10.0 * .1;
bool equals = d1.AlmostEquals(0.0, 0.0000001);
答案 2 :(得分:15)
对于您的简单样本,该测试是可以的。但是这个怎么样:
bool b = ( 10.0 * .1 - 1.0 == 0.0 );
请记住.1是二进制的重复小数,无法准确表示。然后将其与此代码进行比较:
double d1 = 10.0 * .1; // make sure the compiler hasn't optimized the .1 issue away
bool b = ( d1 - 1.0 == 0.0 );
我会让你去做一个测试,看看实际的结果:你更有可能记住它。
答案 3 :(得分:13)
来自Double.Equals的MSDN条目:
比较精确度
Equals方法应该与。一起使用 谨慎,因为两个显然 等值可能是不等的 两者的精度不同 值。以下示例报告 那个Double值.3333和 通过除以1而得到的双是 不相等的。
...
而不是比较平等, 一种推荐的技术涉及 定义可接受的边际 两个值之间的差异(例如 其中一个值的.01%)。如果 差异的绝对值 两个值之间小于或 等于那个边际,差异 可能是由于差异造成的 精度,因此,价值 可能是平等的。下列 示例使用此技术进行比较 .33333和1/3,两个Double值 上一个代码示例找到了 不平等。
另请参阅Double.Epsilon。
答案 4 :(得分:6)
当您比较不同类型的浮点值实现时问题就出现了,例如将float与double进行比较。但是同样的类型,它应该不是问题。
float f = 0.1F;
bool b1 = (f == 0.1); //returns false
bool b2 = (f == 0.1F); //returns true
问题是,程序员有时会忘记进行比较时会发生隐式类型转换(double to float),并导致错误。
答案 5 :(得分:3)
如果数字直接分配给浮点数或双数,那么可以安全地测试零或任何整数,可以用双位表示53位或浮点数用24位。
或者换句话说,你可以随时将double和integer赋值给double,然后将double与同一个整数进行比较,并保证它是相等的。
你也可以通过指定一个整数来开始,并通过坚持添加,减去或乘以整数来进行简单的比较(假设结果小于24位浮点数abd 53位为双数) 。因此,您可以在某些受控条件下将浮点数和双精度数视为整数。
答案 6 :(得分:2)
不,不行。当比较等于0.0时,所谓的非正规化值(次正规)将比较为假(非零),但是当在等式中使用时将被归一化(变为0.0)。因此,使用它作为避免被零除的机制是不安全的。相反,添加1.0并与1.0进行比较。这将确保将所有子范数视为零。
答案 7 :(得分:-1)
试试这个,你会发现==对于double / float来说是不可靠的
double d = 0.1 + 0.2;
bool b = d == 0.3;
以下是Quora的answer。
答案 8 :(得分:-4)
实际上,我认为最好使用以下代码将double值与0.0进行比较:
double x = 0.0;
return (Math.Abs(x) < double.Epsilon) ? true : false;
浮动相同:
float x = 0.0f;
return (Math.Abs(x) < float.Epsilon) ? true : false;