我知道UIKit使用CGFloat,因为它是分辨率无关的坐标系。
但每次我想检查frame.origin.x是否为0时,我都觉得很恶心:
if (theView.frame.origin.x == 0) {
// do important operation
}
当与==,<=,>=,<,>比较时,CGFloat是否容易出现假阳性?
它是一个浮点数,它们有不精确的问题:例如0.0000000000041。
Objective-C在比较时是否会在内部处理这个或者是否会发生原点。读作0的X不与0比较为真?
我想给出一个和其他人不一样的答案。他们很好地回答了你的问题,但可能不是你需要知道的或你真正的问题是什么。
图形中的浮点数很好!但是几乎没有必要直接比较浮点数。你为什么要这么做?图形使用浮点数来定义间隔。比较浮动是否在浮动所定义的区间内总是定义良好的,只需要保持一致,而不需要精确或精确!只要可以分配一个像素(这也是一个间隔!),这就是所有的图形需求。
所以如果你想测试你的点是否在a [0..]宽度[范围,这很好。只要确保你对包含的定义是一致的。例如,总是定义内部是(x>=0 && x < width)。这同样适用于交叉测试或命中测试。
但是,如果您滥用图形坐标作为某种标志,例如查看窗口是否停靠,则不应该这样做。使用一个独立于图形表示层的布尔标志。
另一个可能需要记住的问题是,不同的实现做事情的方式不同。我非常熟悉的一个例子是索尼Playstation 2上的FP单元。与任何X86设备中的IEEE FP硬件相比,它们有显著的差异。引用的文章提到完全缺乏对inf和NaN的支持,而且情况变得更糟。
不太为人所知的是我后来所知道的“一位乘法”错误。对于float x的特定值:
y = x * 1.0;
assert(y == x);
断言将失败。在一般情况下,有时,但不总是,在Playstation 2上FP相乘的结果比等效的IEEE尾数少一位。
我的观点是,您不应该假设将FP代码从一个平台移植到另一个平台会产生相同的结果。任何给定的平台都是内部一致的,因为结果在该平台上不会改变,只是它们可能与另一个平台不一致。例如,X86上的CPython使用64位双精度来表示浮点数,而Cortex MO上的CircuitPython必须使用软件FP,并且只使用32位浮点数。不用说,这会引起差异。
我40多年前学到的一句话今天依然适用。“在计算机上做浮点运算就像移动一堆沙子。每次你做任何事,都会留下一点沙子,捡起一点泥土。”
Playstation是索尼公司的注册商标。