以下 C# 代码不起作用:
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue.Equals(dValue);
那么,问题是:比较 Double 和 Int 的最佳方法是什么?
你真的不能以幼稚的方式比较浮点值和整数值;特别是,因为存在经典的浮点表示挑战。您可以做的就是从另一个中减去一个,看看它们之间的差异是否小于您关心的某个精度,如下所示:
int iValue = 0;
double dValue = 0.0;
var diff = Math.Abs(dValue - iValue);
if( diff < 0.0000001 ) // need some min threshold to compare floating points
return true; // items equal
您确实必须自己定义
equality
对您意味着什么。例如,您可能希望将浮点值舍入到最接近的整数,以便 3.999999981 将“等于”4。或者您可能希望截断该值,因此它实际上是 3。这完全取决于您的情况正在努力实现。
编辑:请注意,我选择 0.0000001 作为示例阈值...您需要自己决定什么精度足以进行比较。只需意识到您需要处于
double
的正常表征范围内,我认为其定义为 Double.Epsilon
。
在任何语言中比较整数和浮点数是否相等都是一个非常糟糕的主意。它适用于非常简单的情况,但在你做了任何数学运算之后,程序执行你想要的操作的可能性会急剧下降。
它与浮点数在二进制数字系统上的存储方式有关。
如果您非常确定要使用它,请创建一个类来创建您自己的带分数的数字。使用一个 int 来维护整数,使用另一个 int 来维护小数。
这实际上取决于您认为“平等”的是什么。如果您希望当且仅当 double 与整数值精确匹配(即没有小数部分)时比较才返回 true,则应该将 int 转换为 double 来进行比较:
bool isEqual = (double)iValue == dValue;
如果像 1.1 这样的东西被认为等于 1,您可以将 double 转换为 int (如果您想完全忽略小数部分),或者如果您想让 1.9 等于 2,则可以将 double 舍入。
如今,唯一一次应该比较类型
double
和 integer
或 long
的值以获得严格相等的情况是,由于某种原因,人们被困在将整数作为浮点值存储或传递时稍后需要将它们转换回来。 在大多数情况下,通过将整型类型强制转换为 double
,然后比较该强制转换的结果,可以最轻松地完成此类转换。 请注意,如果数字超出 ±252范围,则从
long
到 double
的转换可能不精确。 尽管如此,在 64 位 long
可用之前,double
是一种方便的整数存储类型,对于 32 位 int
来说太大了,但足够小,可以由 double
处理。
请注意,如果
long
的标称值与 double
值不精确匹配,但表示最接近的可能 ,则将
double
转换为
long
然后进行比较将产生“相等”结果double
到该值。 如果人们认识到浮点类型实际上并不表示单个精确值,而是表示一系列值,则这种行为是有意义的。
double val1 = 0;
double val2 = 0.0;
if((val1 - Double.Epsilon) < 0)
{
// Put your code here
}
OR
if((val2 - Double.Epsilon) < 0)
{
// Put your code here
}
其中 Double.Epsilon 是 Double 的最低可能值。
因为Epsilon定义了正值的最小表达式 其范围接近于零,两个相似值之间的差异幅度 值必须大于 Epsilon。一般情况下是很多次 大于厄普西隆。因此,我们建议您不要 比较 Double 值是否相等时使用 Epsilon。
如果您还没有使用 double 进行任何计算,则可以直接使用
==
。这是因为整数可以精确地用双精度数表示(仅在 -2^53 和 2^53 之间)。
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue == dValue;
这返回 true。
Equals
不起作用的原因是==
运算符会在比较之前自动将整数转换为双精度型,而Equals
不会,因此会失败。
这个答案有更多信息: https://stackoverflow.com/a/52525223/15714398
如果您使用双精度进行了计算,那么所有的赌注都会被取消,您必须对计算中的有效数字数量进行一些分析。