关于ios:如何安全地将CGFloat放置或嵌入到int?

How to safely floor or ceil a CGFloat to int?

为了计算数组索引,我经常需要将CGFloat转换为int

我对floorf(theCGFloat)ceilf(theCGFloat)的长期看法是,浮点数不准确可能存在问题。

那么,如果我的CGFloat2.0f,但是在内部它被表示为1.999999999999f或者类似的东西,会怎么样呢?我做了floorf,得到了1.0f,它又是一个浮点数。然而,我必须把这个怪兽扔给int,这可能会带来另一个问题。

有没有一个最佳的做法,如何地板或天花板一个float到一个int这样的东西,像2.0不会意外地地板到1和像2.0一样的东西不会意外地被接收到2


快速补充答案

我补充说,这是对那些来这里研究如何使用floorceilCGFloat的人的补充回答。

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

如果需要一个int,那么它可以被铸造成一个。

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

更新

不再需要使用c floorceil函数。您可以使用带舍入规则的swift round()

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

如果不希望修改原始变量,则使用rounded()

笔记

  • 适用于32位和64位体系结构。

另请参见

  • 如何舍入CGfloat

你的问题中有几个误解。

what if my CGFloat is 2.0f but internally it is represented as 1.999999999999f

不可能发生;2.0和所有相当小的整数一样,在浮点中有精确的表示。如果你的CGFloat2.0f,那么它实际上是2.0。

something like 2.0 would never accidentally get ceiled to 2

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

我认为你真正要问的问题是,"假设我做的计算产生了一个不精确的结果,在数学上应该正好是2.0,但实际上要小一些;当我把floor应用于该值时,我得到的是1.0而不是2.0——我如何防止这种情况发生?"

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


编辑-阅读评论以了解此答案不正确的原因:)

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):)