gpt4 book ai didi

ios - 将 NSNumber 实例与 isEqualToNumber 进行比较

转载 作者:行者123 更新时间:2023-11-28 18:57:55 25 4
gpt4 key购买 nike

是的,我已经阅读了 stackoverflow 上关于比较 NSNumber 的其他帖子,但它们似乎都没有完全解决这种特殊情况。
这个解决方案特别糟糕...... NSNumber compare: returning different results
因为建议的解决方案根本不起作用。使用 abs(value1 - value2) < tolerance 从一开始就是有缺陷的,因为小数值被剥离,使得 tolerance 无关紧要。

并且来自 Apple 文档... NSNumber 明确不保证返回的类型将与用于创建它的方法相匹配。换句话说,如果给你一个 NSNumber,你无法确定它是否包含 float、double、int、bool 或其他任何东西。

此外,据我所知,NSNumber isEqualToNumber 是比较两个 NSNumber 的不可信方法。

鉴于这些定义...

NSNumber *float1 = [NSNumber numberWithFloat:1.00001];
NSNumber *double1 = [NSNumber numberWithDouble:1.00001];

如果您运行调试器,然后使用 == 对这些相同的数字进行 2 次比较,则一次失败,而另一次则没有。

p [double1 floatValue] == [float1 floatValue]   **// returns true**
p [double1 doubleValue] == [float1 doubleValue] **// returns false**

如果您使用 isEqualToNumber 比较它们

p [float1 isEqualToNumber:double1]             **// returns false**

因此,如果 isEqualToNumber 将返回 false,假设 NSNumber 的创建是一个黑盒子,可能会在输出时为您提供一些其他类型,我不确定该方法有什么好处。

因此,如果您要对脏进行测试,因为现有值已更改为新值...最简单的方法是什么来处理所有 NSNumber 比较...而不仅仅是 float 和 double , 但所有的 NSNumbers 呢?

似乎转换为字符串值,然后进行比较是最有用的,或者使用 NSNumberFormatter 可能需要大量额外代码。

你有什么想法?

最佳答案

不可能可靠地比较两个 IEEE float 或 double 。这与 NSNumber 无关。这就是 float 的本质。这在 Strange problem comparing floats in objective-C 的简单 C 类型的上下文中进行了讨论。 . 唯一比较 float 的正确方法是通过测试公差。我不知道你所说的“小数值被剥离”是什么意思。在浮点表示中,一些数字总是丢失。

您提供的特定测试值很好地说明了问题。 1.00001 不能用有限的二进制数字精确表示。 Wolfram Alpha是探索这个的好方法,但作为 double ,1.00001 舍入为 1.0000100000000001。作为 float ,它四舍五入为 1.00001001。显然,这些数字并不相等。如果您以不同的方式往返它们,您应该不会对 isEqualToNumber: 失败感到惊讶。这应该清楚为什么您的两个 floatValue 调用确实相等。四舍五入到 float 的精度,它们“足够接近”。

如果要比较 float ,则必须与 epsilon 进行比较。考虑到编译器优化的最新进展,如果您使用 -Ofast(我们变得很大通过允许这样做可以提高性能)。

如果您需要一些特定数量的有效小数位,那么通常最好使用定点表示法。只需按您需要的位数缩放所有内容并以整数形式工作。如果您需要 float ,但只想以 10 为基数(而不是以 2 为基数)工作良好,则使用 NSDecimalNumberNSDecimal。这会将您的问题转移到以 10 为基数的不好的地方。但是,如果您在处理 float ,则必须处理舍入错误。

有关更广泛的讨论,请参阅 "What Every Programmer Should Know About Floating-Point Arithmetic."

关于ios - 将 NSNumber 实例与 isEqualToNumber 进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30227457/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com