I often need to floor or ceil a CGFloat
to an int
, for calculation of an array index.
The problem I permanently see with floorf(theCGFloa
There are a couple misconceptions in your question.
what if my CGFloat is 2.0f but internally it is represented as 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.
something like 2.0 would never accidentally get ceiled to 2
The ceiling of 2.0 is 2; what else would it possibly be?
I think the question that you're really asking is "suppose I do a calculation that produces an inexact result, which mathematically should be 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?"
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?
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 :)
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).
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)
:)
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).
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.
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.
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()
.
Notes
See also