round swift ceil cgfloat

round - ceil swift 3



ReĂșna un CGFloat en Swift (5)

¿Cómo puedo reunir un CGFloat en Swift? He intentado ceil(CDouble(myCGFloat)) pero eso solo funciona en iPad Air y iPhone 5S.

Cuando se ejecuta en otro dispositivo simulado ''NSNumber'' is not a subtype of ''CGFloat'' un error que dice ''NSNumber'' is not a subtype of ''CGFloat''


Actualización : Apple ahora ha definido algunas versiones específicas de CGFloat de funciones comunes como ceil :

func ceil(x: CGFloat) -> CGFloat

... específicamente para hacer frente a la diferencia de 32/64 bits. Si simplemente usa ceil con un argumento CGFloat, ahora debería funcionar en todas las arquitecturas.

Mi respuesta original:

Esto es bastante horrible, creo, pero ¿alguien puede pensar en una mejor manera? #if si no parece funcionar para CGFLOAT_IS_DOUBLE ; Creo que está limitado a crear configuraciones, por lo que puedo ver en la documentación para la compilación condicional .

var x = CGFloat(0.5) #if arch(x86_64) || arch(arm64) var test = ceil(x) #else var test = ceilf(x) #endif


Construyendo fuera de la respuesta de holex. yo si

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

-edición de extensión deedit-

También recientemente convertí esto en una extensión para que Floats pensara que compartiría también :)

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

Esto lo hace para que puedas ser como

var f : Float = 3.3 f.roundToInt()


eso puede ser útil:

func roundUp(value: Double) -> Int { if value == Double(Int(value)) { return Int(value) } else if value < 0 { return Int(value) } else { return Int(value) + 1 } }


La sintaxis más correcta sería probablemente:

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

Para usar CGFloat primero voy a hacer que CGFloat Double y después del techo, lo vuelvo a convertir en CGFloat .

Eso funciona cuando CGFloat se define como CFloat o CDouble .

También podría definir un ceil para flotantes ( Esto se ha implementado realmente en Swift 2 ):

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

Entonces podrás llamar directamente

var roundedF: CGFloat = ceil(f)

mientras se preserva la seguridad del tipo.

De hecho, creo que esta debería ser la solución elegida por Apple, en lugar de tener funciones de ceilf y ceilf separadas porque no tienen sentido en Swift.


Con Swift 3, de acuerdo con sus necesidades, puede elegir una de las 4 formas siguientes de redondear un CGFloat .

# 1. Utilizando el método rounded(_:) protocolo FloatingPoint

FloatingPoint protocolo FloatingPoint proporciona tipos que conforman un método rounded(_:) . rounded(_:) tiene la siguiente declaración:

func rounded(_ rule: FloatingPointRoundingRule) -> Self

Devuelve este valor redondeado a un valor integral usando la regla de redondeo especificada.

El código de Playground a continuación muestra cómo usar rounded(_:) para redondear un valor de 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. Usando la función ceil(_:)

Darwin proporciona una función ceil(_:) que tiene la siguiente declaración:

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

El código de Playground a continuación muestra cómo usar ceil(_:) para redondear un valor de 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 = 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. Usando NSDecimalNumber

NSDecimalNumber ofrece una solución detallada pero potente para redondear números.

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 scale: Int16 = 0 let behavior = NSDecimalNumberHandler(roundingMode: NSDecimalNumber.RoundingMode.up, scale: scale, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true) let roundedValue1 = NSDecimalNumber(value: Double(value1)).rounding(accordingToBehavior: behavior) let roundedValue2 = NSDecimalNumber(value: Double(value2)).rounding(accordingToBehavior: behavior) let roundedValue3 = NSDecimalNumber(value: Double(value3)).rounding(accordingToBehavior: behavior) let roundedValue4 = NSDecimalNumber(value: Double(value4)).rounding(accordingToBehavior: behavior) let roundedValue5 = NSDecimalNumber(value: Double(value5)).rounding(accordingToBehavior: behavior) let roundedValue6 = NSDecimalNumber(value: Double(value6)).rounding(accordingToBehavior: behavior) print(roundedValue1) // prints 0 print(roundedValue2) // prints 0 print(roundedValue3) // prints -1 print(roundedValue4) // prints 1 print(roundedValue5) // prints 1 print(roundedValue6) // prints 1

# 4. Usando el método de protocolo NumberFormatter

Si desea redondear un CGFloat y formatearlo con estilo en la misma operación, puede usar 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")