Finish CGFloat in Swift

How can I combine CGFloat in Swift? I tried ceil(CDouble(myCGFloat)) , but this only works on iPad Air and iPhone 5S.

When I run on another simulated device, I get the error message 'NSNumber' is not a subtype of 'CGFloat'

+70
rounding swift cgfloat ceil
Jun 12 '14 at 10:20
source share
6 answers

Update . Now Apple has defined some versions of common CGFloat features, such as ceil :

 func ceil(x: CGFloat) -> CGFloat 

... specifically to deal with the 32/64-bit difference. If you just use ceil with the CGFloat argument, it should now work on all architectures.

My original answer:

This is pretty terrible, I think, but can anyone think of a better way? #if doesn't seem to work for CGFLOAT_IS_DOUBLE ; I think you are limited to creating configurations, from which 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 
+107
Jun 12 '14 at 10:43
source share

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




# 1. Using CGFloat rounded(_:) CGFloat rounded(_:)

The FloatingPoint protocol provides types that correspond to it, the rounded(_:) method. CGFloat rounded(_:) has the following declaration:

 func rounded(_ rule: FloatingPointRoundingRule) -> CGFloat 

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

The sample Playground code below shows how to use rounded(_:) for a CGFloat value of a CGFloat :

 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 the ceil(_:) function

Darwin provides the ceil(_:) function, which has the following declaration:

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

The Playground code below shows how to use ceil(_:) for the 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 CGFloat and format it with a style in the same operation, you can 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") 
+24
Mar 22 '17 at 13:56 on
source share

The most correct syntax will probably be:

 var f: CGFloat = 2.5 var roundedF = CGFloat(ceil(Double(f))) 

To use ceil , I will first make CGFloat a Double and after the ceiling, I will CGFloat it back in CGFloat .

This works when CGFloat is defined as CFloat or CDouble .

You can also define ceil for a float ( This was actually implemented in Swift 2 ):

 func ceil(f: CFloat) -> CFloat { return ceilf(f) } 

Then you can call directly

 var roundedF: CGFloat = ceil(f) 

while maintaining type safety.

I really believe that this should be the solution Apple chose, instead of the individual ceil and ceilf , because they do not make sense in Swift.

+20
Jun 12 '14 at 12:05
source share

from the Swift standard library, you can also round it in place:

 var value: CGFloat = -5.7 value.round(.up) // -5.0 
+7
Jun 12 '14 at 10:26
source share

Creating a holex response. I did

 func accurateRound(value: Double) -> Int { var d : Double = value - Double(Int(value)) if d < 0.5 { return Int(value) } else { return Int(value) + 1 } } 

-edit edition -

I also recently turned this into an extension for Floats, which I would share :)

 extension Float { func roundToInt() -> Int{ var value = Int(self) var f = self - Float(value) if f < 0.5{ return value } else { return value + 1 } } } 

It makes you just look like

 var f : Float = 3.3 f.roundToInt() 
+5
Sep 17 '14 at 23:11
source share

Use it on Swift 5

 let x = 6.5 // Equivalent to the C 'round' function: print(x.rounded(.toNearestOrAwayFromZero)) // Prints "7.0" // Equivalent to the C 'trunc' function: print(x.rounded(.towardZero)) // Prints "6.0" // Equivalent to the C 'ceil' function: print(x.rounded(.up)) // Prints "7.0" // Equivalent to the C 'floor' function: print(x.rounded(.down)) // Prints "6.0" 
0
Jul 08 '19 at 12:02
source share



All Articles