Round up a CGFloat in Swift
Update: Apple have now defined some CGFloat-specific versions of common functions like ceil
:
func ceil(x: CGFloat) -> CGFloat
...specifically to cope with the 32/64-bit difference. If you simply use ceil
with a CGFloat argument it should now work on all architectures.
My original answer:
This is pretty horrible, I think, but can anyone think of a better way? #if
doesn't seem to work for CGFLOAT_IS_DOUBLE
; I think you're limited to build configurations, from what I can see in the documentation for conditional compilation.
var x = CGFloat(0.5)
#if arch(x86_64) || arch(arm64)
var test = ceil(x)
#else
var test = ceilf(x)
#endif
How to round CGFloat
There are already standard functions with behaviors you might need in <math.h>
such as: floorf
, ceilf
, roundf
, rintf
and nearbyintf
(lasf 'f' means "float" version, versions without it are "double" versions).
It is better to use standard methods not only because they are standard, but because they work better in edge cases.
2013 Update (jessedc)
iOS is no longer only 32 bit. There are a number of other answers to this question that are now more relevant.
Most answers mention importing tgmath.h
- https://stackoverflow.com/a/5352779/184130
- https://stackoverflow.com/a/7695011/184130
How to safely floor or ceil a CGFloat to int?
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?
Swift equivalent of ceilf for CGFloat
The Swift way to do this now is to use rounded(.up)
(or round(.up)
if you want to change the variable in place). Behind the scenes it is using ceil
, which can take a CGFloat
as a parameter and is architecture independent.
let myCGFloat: CGFloat = 3.001
let y = myCGFloat.rounded(.up) // 4.0
This is equivalent to
var myCGFloat: CGFloat = 3.001
let y = ceil(myCGFloat) // 4.0
Any use of ceilf
is no longer necessary.
See also my fuller answer on CGFloat
with various rounding rules.
How to round of CGFloat value
Try this........
NSLog(@"SCALE : %.3f", scale);
NSString *value = [NSString stringWithFormat:@"%.3f", theFloat];
Stolen from Previous SO answer
Rounding a double value to x number of decimal places in swift
You can use Swift's round
function to accomplish this.
To round a Double
with 3 digits precision, first multiply it by 1000, round it and divide the rounded result by 1000:
let x = 1.23556789
let y = Double(round(1000 * x) / 1000)
print(y) /// 1.236
Unlike any kind of printf(...)
or String(format: ...)
solutions, the result of this operation is still of type Double
.
EDIT:
Regarding the comments that it sometimes does not work, please read this: What Every Programmer Should Know About Floating-Point Arithmetic
Swift: Rounding float to nearest custom multiplier
You can use the same approach as rounding to a power of 10 here.
When you want to round to the nearest 0.1, you multiply by 10, round, then divide by 10. When you want to round to the nearest 0.01, you multiply by 100, round, then divide by 100.
See the pattern here? The number you multiply and divide by is always 1 over the granularity!
So for the granularity of 0.25, you multiply and divide by 4:
print(round(0.3 * 4) / 4)
// or
print(round(0.3 / 0.25) * 0.25)
More generally, given a granularity: Double
and a number to round x: Double
, we can round it like this:
let rounded = round(x / granularity) * granularity
How to invert a CGFloat in Swift 3?
It's simply like this.
let invert: CGFloat = 100
let a: CGFloat = 0
let b = invert - a
Or Simply
let b = 100 - a
How to round a Double to the nearest Int in swift?
There is a round
available in the Foundation
library (it's actually in Darwin
, but Foundation
imports Darwin
and most of the time you'll want to use Foundation
instead of using Darwin
directly).
import Foundation
users = round(users)
Running your code in a playground and then calling:
print(round(users))
Outputs:
15.0
round()
always rounds up when the decimal place is >= .5
and down when it's < .5
(standard rounding). You can use floor()
to force rounding down, and ceil()
to force rounding up.
If you need to round to a specific place, then you multiply by pow(10.0, number of places)
, round
, and then divide by pow(10, number of places)
:
Round to 2 decimal places:
let numberOfPlaces = 2.0
let multiplier = pow(10.0, numberOfPlaces)
let num = 10.12345
let rounded = round(num * multiplier) / multiplier
print(rounded)
Outputs:
10.12
Note: Due to the way floating point math works, rounded
may not always be perfectly accurate. It's best to think of it more of an approximation of rounding. If you're doing this for display purposes, it's better to use string formatting to format the number rather than using math to round it.
Related Topics
How to Save Data from Cloud Firestore to a Variable in Swift
Try, Try! & Try? What's the Difference, and When to Use Each
Alamofire Asynchronous Completionhandler For Json Request
Determining If Swift Dictionary Contains Key and Obtaining Any of Its Values
How to Silence a Warning in Swift
Spritekit Physics in Swift - Ball Slides Against Wall Instead of Reflecting
The "Prefs" Url Scheme Is Not Working in iOS 10 (Beta 1 & 2)
Swift - Increment Label With Stepper in Tableview Cell
Check If Key Exists in Dictionary of Type [Type:Type]
Array Element Cannot Be Bridged to Objective-C
Should Conditional Compilation Be Used to Cope With Difference in Cgfloat on Different Architectures
Swift: How to Detect Linear Type Barcodes
Setting the Timelineprovider Refresh Interval For Widget
How to Unittest Combine Cancellables
Println Dictionary Has "Optional"