Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Round up a CGFloat in Swift

How can I round up a CGFloat in Swift? I've tried ceil(CDouble(myCGFloat)) but that only works on iPad Air & iPhone 5S.

When running on another simulated device I get an error saying 'NSNumber' is not a subtype of 'CGFloat'

like image 745
Oskar Persson Avatar asked Jun 12 '14 10:06

Oskar Persson


People also ask

How do you round a double in Swift?

We can round a double to the nearest Int by using the round() method in Swift. If the decimal value is >=. 5 then it rounds up to the nearest value. for example, it rounds the 15.7 to 16.0 .

What is floor in Swift?

The floor() function in Swift returns the next largest integer that is less than or equal to a specified number.

What is a float Swift?

Swift provides two signed floating-point number types: Double represents a 64-bit floating-point number. Float represents a 32-bit floating-point number.


Video Answer


2 Answers

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 
like image 97
Matt Gibson Avatar answered Sep 30 '22 13:09

Matt Gibson


With Swift 5, you can choose one of the 3 following paths in order to round up a CGFloat.


#1. Using CGFloat's rounded(_:) method

FloatingPoint protocol gives types that conform to it a rounded(_:) method. CGFloat's rounded(_:) has the following declaration:

func rounded(_ rule: FloatingPointRoundingRule) -> CGFloat 

Returns this value rounded to an integral value using the specified rounding rule.

The Playground sample code below shows how to use rounded(_:) in order to round up a CGFloat value:

import CoreGraphics  let value1: CGFloat = -0.4 let value2: CGFloat = -0.5 let value3: CGFloat = -1 let value4: CGFloat = 0.4 let value5: CGFloat = 0.5 let value6: CGFloat = 1  let roundedValue1 = value1.rounded(.up) let roundedValue2 = value2.rounded(.up) let roundedValue3 = value3.rounded(.up) let roundedValue4 = value4.rounded(.up) let roundedValue5 = value5.rounded(.up) let roundedValue6 = value6.rounded(.up)  print(roundedValue1) // prints -0.0 print(roundedValue2) // prints -0.0 print(roundedValue3) // prints -1.0 print(roundedValue4) // prints 1.0 print(roundedValue5) // prints 1.0 print(roundedValue6) // prints 1.0 

#2. Using ceil(_:) function

Darwin provides a ceil(_:) function that has the following declaration:

func ceil<T>(_ x: T) -> T where T : FloatingPoint 

The Playground code below shows how to use ceil(_:) in order to round up a CGFloat value:

import CoreGraphics  let value1: CGFloat = -0.4 let value2: CGFloat = -0.5 let value3: CGFloat = -1 let value4: CGFloat = 0.4 let value5: CGFloat = 0.5 let value6: CGFloat = 1  let roundedValue1 = ceil(value1) let roundedValue2 = ceil(value2) let roundedValue3 = ceil(value3) let roundedValue4 = ceil(value4) let roundedValue5 = ceil(value5) let roundedValue6 = ceil(value6)  print(roundedValue1) // prints -0.0 print(roundedValue2) // prints -0.0 print(roundedValue3) // prints -1.0 print(roundedValue4) // prints 1.0 print(roundedValue5) // prints 1.0 print(roundedValue6) // prints 1.0 

#3. Using NumberFormatter

If you want to round up a CGFloat and format it with style in the same operation, you may use NumberFormatter.

import Foundation import CoreGraphics  let value1: CGFloat = -0.4 let value2: CGFloat = -0.5 let value3: CGFloat = -1 let value4: CGFloat = 0.4 let value5: CGFloat = 0.5 let value6: CGFloat = 1  let formatter = NumberFormatter() formatter.numberStyle = NumberFormatter.Style.decimal formatter.roundingMode = NumberFormatter.RoundingMode.ceiling formatter.maximumFractionDigits = 0  let roundedValue1 = formatter.string(for: value1) let roundedValue2 = formatter.string(for: value2) let roundedValue3 = formatter.string(for: value3) let roundedValue4 = formatter.string(for: value4) let roundedValue5 = formatter.string(for: value5) let roundedValue6 = formatter.string(for: value6)  print(String(describing: roundedValue1)) // prints Optional("-0") print(String(describing: roundedValue2)) // prints Optional("-0") print(String(describing: roundedValue3)) // prints Optional("-1") print(String(describing: roundedValue4)) // prints Optional("1") print(String(describing: roundedValue5)) // prints Optional("1") print(String(describing: roundedValue6)) // prints Optional("1") 
like image 34
Imanou Petit Avatar answered Sep 30 '22 13:09

Imanou Petit