如何安全地地板或小区一CGFloat的为int?(How to safely floor or ce

2019-07-31 01:08发布

我经常需要地板或CEIL一个CGFloat一个int ,对于数组索引的计算。

我看到永久的问题floorf(theCGFloat)ceilf(theCGFloat)是有可能与浮点不准确的麻烦。

所以,如果我有什么CGFloat2.0f但是在内部它被表示为1.999999999999f或类似的东西。 我不floorf并获得1.0f ,这是再次浮动。 然而,我必须施放此兽为int可以引入另一个问题。

是否有一个最佳实践如何楼或小区一floatint ,使得像2.0永远不会意外遭到地板到1和像2.0永远不会意外遭到ceiled到2

Answer 1:

有你的问题一对夫妇的误解。

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

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

像2.0永远不会意外遭到ceiled 2

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


我觉得你真的问的是这个问题:“假设我这样做会产生一个不精确的结果,这在数学上应该是准确2.0,但实际上是略小于计算;当我申请floor到该值,我得到1.0而不是2.0 - 如何避免发生这种情况?”

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



Answer 2:

斯威夫特补充回答

我加入这为那些谁到这里来寻找如何使用补充答案floorceilCGFloat (像我一样)。

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功能了。 您可以使用雨燕round()以四舍五入的规则 。

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

如果你不希望修改原始变量,然后用rounded()

笔记

  • 可工作在32位和64位体系结构。

也可以看看

  • 如何圆CGFloat的


Answer 3:

编辑 - 读的原因的评论,为什么这个答案是不正确的:)

铸造floatint是一个隐式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) :)



文章来源: How to safely floor or ceil a CGFloat to int?