ios 如何安全地将 CGFloat 设置为 int 或 ceil?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11993981/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to safely floor or ceil a CGFloat to int?
提问by Proud Member
I often need to floor or ceil a CGFloat
to an int
, for calculation of an array index.
我经常需要将 a 或 ceil 设置CGFloat
为 an int
,以计算数组索引。
The problem I permanently see with floorf(theCGFloat)
or ceilf(theCGFloat)
is that there can be troubles with floating point inaccuracies.
我看到永久的问题floorf(theCGFloat)
或者ceilf(theCGFloat)
是有可与浮点不准确的麻烦。
So what if my CGFloat
is 2.0f
but internally it is represented as 1.999999999999f
or something like that. I do floorf
and get 1.0f
, which is a float again. And yet I must cast this beast to int which may introduce another problem.
那么,如果我CGFloat
是,2.0f
但在内部它被表示为1.999999999999f
或类似的东西。I do floorf
and get 1.0f
,这又是一个浮点数。然而我必须将这个野兽转换为 int ,这可能会引入另一个问题。
Is there a best practice how to floor or ceil a float
to an int
such that something like 2.0
would never accidentally get floored to 1
and something like 2.0
would never accidentally get ceiled to 2
?
是否有最佳实践如何将 a 限制float
在 a 上int
,以便像2.0
这样的1
东西2.0
永远不会意外地被踩到,而像这样的东西永远不会意外地被限制到2
?
回答by Suragch
Swift supplemental answer
快速补充答案
I am adding this as a supplemental answer for those who come here looking how to use floor
and ceil
with a CGFloat
(like I did).
我将此添加为那些来这里寻找如何使用floor
和ceil
使用CGFloat
(就像我一样)的人的补充答案。
var myCGFloat: CGFloat = 3.001
floor(myCGFloat) // 3.0
ceil(myCGFloat) // 4.0
And if an Int
is needed, then it can be cast to one.
如果Int
需要an ,则可以将其强制转换为 one。
var myCGFloat: CGFloat = 3.001
Int(floor(myCGFloat)) // 3
Int(ceil(myCGFloat)) // 4
Update
更新
There is no need to use the C floor
and ceil
functions anymore. You can use the Swift round()
with rounding rules.
不再需要使用 Cfloor
和ceil
函数。您可以使用round()
带有舍入规则的 Swift 。
var myCGFloat: CGFloat = 3.001
myCGFloat.round(.down) // 3.0
myCGFloat.round(.up) // 4.0
If you don't wish to modify the original variables, then use rounded()
.
如果您不想修改原始变量,请使用rounded()
.
Notes
笔记
- Works with both 32 and 64 bit architectures.
- 适用于 32 位和 64 位架构。
See also
也可以看看
回答by Stephen Canon
There are a couple misconceptions in your question.
你的问题有几个误解。
what if my CGFloat is 2.0f but internally it is represented as 1.999999999999f
如果我的 CGFloat 是 2.0f 但在内部它表示为 1.999999999999f 怎么办
can't happen; 2.0, like all reasonably small integers, has an exact representation in floating-point. If your CGFloat
is 2.0f
, then it really is 2.0.
不可能发生;2.0 与所有合理的小整数一样,具有精确的浮点表示。如果您CGFloat
是2.0f
,那么它确实是 2.0。
something like 2.0 would never accidentally get ceiled to 2
像 2.0 这样的东西永远不会意外地被限制到 2
The ceiling of 2.0 is2; what else would it possibly be?
2.0的上限是2;还有什么可能是?
I think the question that you're really asking is "suppose I do a calculation that produces an inexact result, which mathematically shouldbe exactly 2.0, but is actually slightly less; when I apply floor
to that value, I get 1.0 instead of 2.0--how do I prevent this?"
我认为您真正要问的问题是“假设我进行的计算产生了不精确的结果,从数学上讲,该结果应该正好是 2.0,但实际上略小;当我应用floor
该值时,我得到 1.0 而不是 2.0- ——我该如何预防?”
That's actually a fairly subtle question that doesn't have a single "right" answer. How have you computed the input value? What are you going to do with the result?
这实际上是一个相当微妙的问题,没有单一的“正确”答案。你是如何计算输入值的?你打算怎么处理这个结果?
回答by deanWombourne
EDIT - read the comments for reasons why this answer isn't right :)
编辑 - 阅读评论,了解为什么这个答案不正确:)
Casting a float
to an int
is an implicit floorf
i.e. (int)5.9
is 5
. If you don't mind that then just cast :)
将 a 转换float
为 anint
是一个隐式的floorf
ie (int)5.9
is 5
。如果你不介意,那就投吧:)
If you want to round up then just cast the result of a ceilf
- casting after rounding shouldn't introduce any errors at all (or, if you want, add one before casting i.e. `(int)(5.9+1)' is '6' - same as rounding up).
如果你想四舍五入,那么只需ceilf
在四舍五入后转换 - 转换的结果根本不应该引入任何错误(或者,如果你想,在转换之前添加一个,即`(int)(5.9+1)' is '6 ' - 与四舍五入相同)。
To round to the nearest, just add 0.5 - (int)(5.9+0.5)
is 6
but (int)(5.4+0.5)
is 5
. Though I would just use roundf(5.9)
:)
要四舍五入,只需添加 0.5 - (int)(5.9+0.5)
is 6
but (int)(5.4+0.5)
is 5
。虽然我只会使用roundf(5.9)
:)