这个问题与语言无关,但代码是用Java编写的。
我们都听说过,比较浮点数是否相等通常是错误的。但是,如果我想比较两个完全相同的文字浮点值(或表示转换为浮点数的完全相同的文字值的字符串),该怎么办?
我很确定这些数字是完全相等的(好吧,因为它们在二进制中必须相等——完全相同的东西怎么会产生两个不同的二进制数?!)但我想确定一下。
案例1:
void test1() {
float f1 = 4.7;
float f2 = 4.7;
print(f1 == f2);
}
案例2:
class Movie {
String rating; // for some reason the type is String
}
void test2() {
movie1.rating = "4.7";
movie2.rating = "4.7";
float f1 = Float.parse(movie1.rating);
float f2 = Float.parse(movie2.rating);
print(f1 == f2);
}
在这两种情况下,表达式f1==f2
应导致true
。我说得对吗?如果它们具有相同的文字浮点值或字符串值,我是否可以安全地比较评级
s是否相等?
是的,你可以像这样比较浮动。问题是,即使4.7在转换为浮点数时不是4.7,它也会一致地转换为相同的值。
一般来说,这样比较浮动本身并没有错。但是对于更复杂的数学,你可能需要使用Math.round()或者设置一个“相同”的差异范围,两者应该在这个范围内被算作“相同”。
不动点数也有任意性。例如
1,000,000,001
比
1.000,000,000
这两个数字不同吗?这取决于你需要的精度。但大多数情况下这些数字在功能上是相同的
对相同的编译时常量的计算结果是一致的。
如果你想一想,它们一定是一样的,因为只有一个编译器,它会将文本决定性地转换为它们的浮点表示。
有一条经验法则,您应该应用于所有编程经验法则(经验法则?):
它们过于简单化,如果推进得太远,将导致愚蠢的决策。如果你不能完全理解经验法则背后的意图,你就会陷入困境。也许经验法则仍然是一个净积极因素(不假思索地应用它会改善事情,而不是让事情变得更糟),但它会造成损害,而且无论如何它都不能在辩论中用作论据。
因此,考虑到这一点,很明显,问这个问题是没有意义的:
"鉴于经验法则'不使用==比较浮动'存在,它总是不好吗?"。
答案是非常明显的:嗯,不。这并不总是坏事,因为经验法则基本上是根据定义的,如果不是根据常识的话,永远不会适用。
那么让我们把它分解一下。
为什么有一个经验法则,你不应该==比较浮动?
您的问题表明您已经知道这一点:这是因为对IEEE754概念(如java的double
或float
等)表示的浮点进行任何数学运算都是不精确的(与java的BigDecimal
等概念相比,这是精确的*)。
当你面对一条经验法则时,当你摸索经验法则存在的原因并意识到它不适用于你的场景时,做你应该做的事情:完全忽略它。
也许你的问题可以归结为:我想我摸索到了经验法则,但也许我错过了什么;除了“浮点数学引入了会搞砸==比较的小偏差”,这不适用于这种情况,还有其他原因吗这个我不知道的经验法则?
在这种情况下,我的回答是:据我所知,没有。
*)但是BigDecimal有它自己的相等问题,例如:两个BigDecimal对象是否精确地表示同一个数学数,但配置为以不同的比例渲染“相等”?这取决于您的观点是它们是数字还是表示精确小数点的对象,以及一些元属性,包括如何渲染它,以及在明确要求时如何进行取整。值得一提的是,等于
BD的实现,它必须做出一个索菲式的选择,并在平等含义的两种同样有效的解释之间进行选择,选择“我代表一个数字”,而不是“我代表一个数元以及一堆元数据”。所有JPA/Hibernate堆栈中都存在相同的sophie选择:JPA对象是否表示“数据库中的一行”(因此,相等仅由主键值定义,如果尚未保存,两个对象不能相等,甚至不能相等,除非具有相同的引用标识),或者它是否表示该行表示的内容,例如,一名学生,而不是“数据库中代表一名学生的一行”,在这种情况下,unid是一个与身份无关的字段,而所有其他字段(姓名、生日、社会保险号等)都是。平等是困难的。
比较两个NumPy数组是否相等的最简单方法是什么(其中相等定义为:A=B iff,用于所有索引i:
我做了这个扩展方法来检查一个类型是否实现了一个接口。要使其正常工作,它需要比较两种类型。然而,这种比较似乎并不现实: 这是我比较失败的情况: 正如注释中提到的,如果我比较类型名,那么它总是按照预期工作。我想知道这是怎么回事。
本文向大家介绍JavaScript比较两个对象是否相等的方法,包括了JavaScript比较两个对象是否相等的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JavaScript比较两个对象是否相等的方法。分享给大家供大家参考。具体如下: 在Python中可以通过cmp()内建函数来比较两个对象所包涵的数据是否相等(数组、序列、字典)。但是在javascript语言中并没有相关的实现。
问题内容: 比较两个NumPy数组是否相等的最简单方法是什么(其中相等定义为:对于所有索引i:,A = B iff )? 简单地使用就会给我一个布尔数组: 我是否必须确定该数组的元素是否相等,或者是否有更简单的比较方法? 问题答案: 测试数组(A == B)的所有值是否均为True。 注意:也许您还想测试A和B形状,例如 特殊情况和替代方法 (来自dbaupp的回答和yoavram的评论) 应当指
如何比较两个javascript集?我尝试使用和但都返回false。 这两个集合是等价的,因为根据定义,集合没有顺序(至少通常没有)。我看了MDN上的集合的留档,没有发现任何有用的东西。有人知道怎么做吗?
问题内容: 如果我想找出两个键中是否没有一个键与另一个键不同,并且该键的值彼此匹配,如何最好地比较两个键。 将A与B进行比较时,由于B和D键的不同,它应该会失败。 如何最好地比较未排序的哈希图? 问题答案: 做一个支票上两者秒。 注意: 如果您包含键,那没有问题,但是如果您的Map包含类型键,则需要确保您的类实现了。