How to safely floor or ceil a CGFloat to int? How to safely floor or ceil a CGFloat to int? ios ios

How to safely floor or ceil a CGFloat to int?


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.001floor(myCGFloat) // 3.0ceil(myCGFloat) // 4.0

And if an Int is needed, then it can be cast to one.

var myCGFloat: CGFloat = 3.001Int(floor(myCGFloat)) // 3Int(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.001myCGFloat.round(.down) // 3.0myCGFloat.round(.up) // 4.0

If you don't wish to modify the original variables, then use rounded().

Notes

  • Works with both 32 and 64 bit architectures.

See also


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