5 ответов:
обновление: Apple теперь определили некоторые CGFloat-конкретные версии общих функций, таких как
ceil:func ceil(x: CGFloat) -> CGFloat...в частности, чтобы справиться с 32/64-битной разницей. Если вы просто используете
ceilС аргументом CGFloat теперь он должен работать на всех архитектурах.мой оригинальный ответ:
это довольно ужасно, я думаю, но может ли кто-нибудь придумать лучший способ?
#ifкажется, не работает дляCGFLOAT_IS_DOUBLE; Я думаю, что вы ограничены построить конфигурации, от чего я вижу в документации для условной компиляции.var x = CGFloat(0.5) #if arch(x86_64) || arch(arm64) var test = ceil(x) #else var test = ceilf(x) #endif
наиболее правильный синтаксис, вероятно, будет:
var f: CGFloat = 2.5 var roundedF = CGFloat(ceil(Double(f)))использовать
ceilЯ сначала сделаюCGFloataDoubleи после потолка, я преобразовать его обратно вCGFloat.это работает, когда
CGFloatопределяется какCFloatилиCDouble.вы также можете определить
ceilдля поплавков (это было фактически реализовано в Swift 2):func ceil(f: CFloat) -> CFloat { return ceilf(f) }тогда вы сможете позвонить прямо
var roundedF: CGFloat = ceil(f)при сохранении безопасности типа.
Я на самом деле считаю, что это должно быть решение, выбранное Apple, вместо того, чтобы иметь отдельный
ceilиceilfфункции, потому что они не имеют смысла в Swift.
С Swift 3, в соответствии с вашими потребностями, вы можете выбрать один из 4 следующим образом чтобы окружить a
CGFloat.
#1. Используя
FloatingPointпротоколrounded(_:)метод
FloatingPointпротокол дает типы, которые соответствуют ему arounded(_:)метод.rounded(_:)есть следующее объявление:func rounded(_ rule: FloatingPointRoundingRule) -> Selfвозвращает это значение, округленное до целого значения с использованием указанного округления правило.
код игровой площадки ниже показывает, как использовать
rounded(_:)для того, чтобы округлить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. Используя
ceil(_:)функцииДарвин предоставляет
ceil(_:)функция, которая имеет следующий вид:public func ceil<T : FloatingPoint>(_ x: T) -> Tкод игровой площадки ниже показывает, как использовать
ceil(_:)для того, чтобы округлить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. С помощью
NSDecimalNumber
NSDecimalNumberпредлагает подробное, но мощное решение для округления чисел.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. Используя
NumberFormatterесли вы хотите, чтобы округлить
CGFloatи форматировать его со стилем в той же операции, вы можете использовать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")
отталкиваясь от ответа холекса. Я сделал
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 extension edition -
Я также недавно превратил это в расширение для поплавков думал, что я бы тоже поделился:)
extension Float { func roundToInt() -> Int{ var value = Int(self) var f = self - Float(value) if f < 0.5{ return value } else { return value + 1 } } }Это делает его так что вы можете просто быть как
var f : Float = 3.3 f.roundToInt()
С Стандартная Библиотека Swift вы также можете округлить его на месте:
var value: CGFloat = -5.7 value.round(.up) // -5.0
Comments