如何安全地将CGFloat放置或嵌入到int?

时间:2012-08-16 19:16:49

标签: ios math floating-point floating-accuracy floating-point-precision

我经常需要将CGFloat置于或int,以计算数组索引。

我在floorf(theCGFloat)ceilf(theCGFloat)中永久看到的问题是浮点不准确可能会出现问题。

那么,如果我的CGFloat2.0f,但在内部它被表示为1.999999999999f或类似的东西。我做floorf并获得1.0f,这又是一个浮动。然而,我必须将这种野兽施放到int,这可能会引入另一个问题。

最佳做法是如何将float置于int2.0,以便1之类的内容永远不会意外地落入2.0之类的内容,例如2 {1}}永远不会被意外地哄骗{{1}}?

3 个答案:

答案 0 :(得分:23)

迅速补充答案

对于那些来到这里寻找如何使用floorceil CGFloat的人(就像我做的那样),我将其添加为补充答案。

var myCGFloat: CGFloat = 3.001
floor(myCGFloat) // 3.0
ceil(myCGFloat) // 4.0

如果需要Int,则可以将其转换为一个。

var myCGFloat: CGFloat = 3.001
Int(floor(myCGFloat)) // 3
Int(ceil(myCGFloat)) // 4

<强>更新

不再需要使用C floorceil函数。您可以将Swift round()rounding rules一起使用。

var myCGFloat: CGFloat = 3.001
myCGFloat.round(.down) // 3.0
myCGFloat.round(.up) // 4.0

如果您不想修改原始变量,请使用rounded()

备注

  • 适用于32位和64位架构。

另见

答案 1 :(得分:20)

你的问题有几个误解。

  
    

如果我的CGFloat是2.0f但在内部它表示为1.999999999999f

  

不可能发生;与所有合理的小整数一样,2.0具有浮点的精确表示。如果您的CGFloat2.0f,那么它确实是2.0。

  
    像2.0这样的东西永远不会意外地被淹没到2

  

2.0 的上限是 2;还有什么可能呢?


我认为你真正要问的问题是“假设我做了一个产生不精确结果的计算,在数学上应该正好是2.0,但实际上稍微少一点;当我申请时{ {1}}对于那个值,我得到的是1.0而不是2.0 - 我该如何防止这种情况?“

这实际上是一个相当微妙的问题,没有一个“正确”的答案。你是如何计算输入值的?你打算怎么处理这个结果?

答案 2 :(得分:4)

编辑 - 阅读评论,说明为什么这个答案不对:)

float投射到int是一个隐含的floorf,即(int)5.95。如果你不介意那么只是施放:)

如果你想要向上舍入然后只是转换ceilf的结果 - 在舍入后不应该引入任何错误(或者,如果你想要,在转换之前添加一个,即`(int)( 5.9 + 1)'是'6' - 与四舍五入相同。

要舍入到最近,只需添加0.5 - (int)(5.9+0.5)6,但(int)(5.4+0.5)5。虽然我只想使用roundf(5.9):)