developer tip

Swift에서 CGFloat 반올림

copycodes 2020. 10. 23. 08:00
반응형

Swift에서 CGFloat 반올림


Swift에서 CGFloat를 어떻게 반올림 할 수 있습니까? 시도 ceil(CDouble(myCGFloat))했지만 iPad Air 및 iPhone 5S에서만 작동합니다.

다른 시뮬레이션 된 장치에서 실행할 때 다음과 같은 오류가 발생합니다. 'NSNumber' is not a subtype of 'CGFloat'


업데이트 : Apple은 이제 다음과 같은 공통 기능의 일부 CGFloat 특정 버전을 정의했습니다 ceil.

func ceil(x: CGFloat) -> CGFloat

... 특히 32/64 비트 차이에 대처하기 위해. ceilCGFloat 인수와 함께 사용 하면 이제 모든 아키텍처에서 작동합니다.

내 원래 대답 :

이것은 꽤 끔찍한 일이라고 생각하지만 누구든지 더 나은 방법을 생각할 수 있습니까? #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

Swift 5를 사용하면 다음 3 가지 경로 중 하나를 선택 하여 CGFloat.


#1. 사용 CGFloatrounded(_:)방법을

FloatingPoint프로토콜은이를 따르는 유형에 rounded(_:)메소드를 제공합니다. CGFloatrounded(_:)선언은 다음과 같습니다.

func rounded(_ rule: FloatingPointRoundingRule) -> CGFloat

지정된 반올림 규칙을 사용하여 정수 값으로 반올림 된이 값을 리턴합니다.

아래의 플레이 그라운드 샘플 코드 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(_:)기능 사용

Darwinceil(_:)다음 선언이 있는 함수를 제공합니다 .

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

아래의 플레이 그라운드 코드 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

#삼. 사용NumberFormatter

CGFloat동일한 작업에서 a를 반올림하고 스타일로 서식을 지정하려면 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")

가장 정확한 구문은 다음과 같습니다.

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

사용하려면 ceil먼저 CGFloata를 Double만들고 천장 후에 다시 CGFloat.

CGFloatCFloat또는 로 정의 될 때 작동합니다 CDouble.

ceilfor floats를 정의 할 수도 있습니다 ( 실제로 Swift 2에서 구현되었습니다 ).

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

그러면 직접 전화 할 수 있습니다.

var roundedF: CGFloat = ceil(f)

형식 안전성을 유지하면서

사실이 대신 별도의 필요없이 애플이 선택한 해결책이 될 것으로 판단 ceil하고 ceilf그들이 스위프트에 맞지 않는 것들 때문에 기능.


에서 스위프트 표준 라이브러리 는 자리에서 그것을 모아뿐만 아니라 수 있습니다 :

var value: CGFloat = -5.7
value.round(.up) // -5.0

Building off of holex's answer. 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 extension edition-

I also recently turned this into an extension for Floats thought I'd share as well :)

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

This is makes it so you can just be like

var f : Float = 3.3
f.roundToInt()

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"

참고URL : https://stackoverflow.com/questions/24181992/round-up-a-cgfloat-in-swift

반응형