Swift의 정밀 문자열 형식 지정자
다음은 이전에 플로트를 소수점 두 자리로 잘라낸 방법입니다.
NSLog(@" %.02f %.02f %.02f", r, g, b);
서류와 eBook을 확인해 보았지만 아직 파악하지 못했습니다.감사합니다!
다음 코드:
import Foundation // required for String(format: _, _)
print(String(format: "a float number: %.2f", 1.0321))
출력:
a float number: 1.03
David의 답변에 따라 지금까지 나의 가장 좋은 해결책은 다음과 같습니다.
import Foundation
extension Int {
func format(f: String) -> String {
return String(format: "%\(f)d", self)
}
}
extension Double {
func format(f: String) -> String {
return String(format: "%\(f)f", self)
}
}
let someInt = 4, someIntFormat = "03"
println("The integer number \(someInt) formatted with \"\(someIntFormat)\" looks like \(someInt.format(someIntFormat))")
// The integer number 4 formatted with "03" looks like 004
let someDouble = 3.14159265359, someDoubleFormat = ".3"
println("The floating point number \(someDouble) formatted with \"\(someDoubleFormat)\" looks like \(someDouble.format(someDoubleFormat))")
// The floating point number 3.14159265359 formatted with ".3" looks like 3.142
저는 이것이 포맷 작업을 데이터 유형에 직접 연결하는 가장 Swift와 유사한 솔루션이라고 생각합니다.포맷 작업의 내장 라이브러리가 어딘가에 있을 수도 있고, 곧 출시될 수도 있습니다.그 언어는 아직 베타 버전이라는 것을 명심하세요.
찾았습니다String.localizedStringWithFormat
잘 합니다.
예:
let value: Float = 0.33333
let unit: String = "mph"
yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
이것은 복잡한 솔루션이 필요 없는 매우 빠르고 간단한 방법입니다.
let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
여기서 대부분의 답변은 유효합니다.그러나 숫자 형식을 자주 지정할 경우에는 형식이 지정된 문자열을 반환하는 메서드를 추가하도록 Float 클래스를 확장하는 것이 좋습니다.아래 코드 예제를 참조하십시오.이것은 숫자 포맷터와 확장자를 사용하여 동일한 목표를 달성합니다.
extension Float {
func string(fractionDigits:Int) -> String {
let formatter = NSNumberFormatter()
formatter.minimumFractionDigits = fractionDigits
formatter.maximumFractionDigits = fractionDigits
return formatter.stringFromNumber(self) ?? "\(self)"
}
}
let myVelocity:Float = 12.32982342034
println("The velocity is \(myVelocity.string(2))")
println("The velocity is \(myVelocity.string(1))")
콘솔에 다음이 표시됩니다.
The velocity is 12.33
The velocity is 12.3
SWIFT 3.1 업데이트
extension Float {
func string(fractionDigits:Int) -> String {
let formatter = NumberFormatter()
formatter.minimumFractionDigits = fractionDigits
formatter.maximumFractionDigits = fractionDigits
return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
}
}
문자열 보간으로는 (아직) 할 수 없습니다.여전히 NSString 포맷이 최선입니다.
println(NSString(format:"%.2f", sqrt(2.0)))
파이썬에서 추론해보면, 합리적인 구문은 다음과 같습니다.
@infix func % (value:Double, format:String) -> String {
return NSString(format:format, value)
}
그러면 다음과 같은 용도로 사용할 수 있습니다.
M_PI % "%5.3f" // "3.142"
모든 숫자 유형에 대해 유사한 연산자를 정의할 수 있습니다. 안타깝게도 제네릭을 사용할 수 있는 방법을 찾지 못했습니다.
스위프트 5 업데이트
적어도 스위프트 5부터는String
를 직접 합니다.format:
사용할 NSString
리고그고.@infix
속성이 더 이상 필요하지 않습니다. 즉, 위의 샘플은 다음과 같이 작성해야 합니다.
println(String(format:"%.2f", sqrt(2.0)))
func %(value:Double, format:String) -> String {
return String(format:format, value)
}
Double.pi % "%5.3f" // "3.142"
왜 그렇게 복잡하게 만드는 거지?대신 다음을 사용할 수 있습니다.
import UIKit
let PI = 3.14159265359
round( PI ) // 3.0 rounded to the nearest decimal
round( PI * 100 ) / 100 //3.14 rounded to the nearest hundredth
round( PI * 1000 ) / 1000 // 3.142 rounded to the nearest thousandth
Playground에서 작동합니다.
PS: 솔루션 출처: http://rrike.sh/xcode/rounding-various-decimal-places-swift/
import Foundation
extension CGFloat {
var string1: String {
return String(format: "%.1f", self)
}
var string2: String {
return String(format: "%.2f", self)
}
}
사용.
let offset = CGPoint(1.23, 4.56)
print("offset: \(offset.x.string1) x \(offset.y.string1)")
// offset: 1.2 x 4.6
은 루비 /을 다시 입니다.%
연산자:
// Updated for beta 5
func %(format:String, args:[CVarArgType]) -> String {
return NSString(format:format, arguments:getVaList(args))
}
"Hello %@, This is pi : %.2f" % ["World", M_PI]
iOS 15+ 이후에는 이 솔루션이 권장됩니다.
2.31234.formatted(.number.precision(.fractionLength(1)))
세부 사항
- Xcode 9.3, Swift 4.1
- Xcode 10.2.1(10E1001), Swift 5
솔루션 1
(5.2).rounded()
// 5.0
(5.5).rounded()
// 6.0
(-5.2).rounded()
// -5.0
(-5.5).rounded()
// -6.0
funcround(_ 규칙:부동 소수점 반올림 규칙) -> 더블
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"
var x = 5.2
x.round()
// x == 5.0
var y = 5.5
y.round()
// y == 6.0
var z = -5.5
z.round()
// z == -6.0
// Equivalent to the C 'round' function:
var w = 6.5
w.round(.toNearestOrAwayFromZero)
// w == 7.0
// Equivalent to the C 'trunc' function:
var x = 6.5
x.round(.towardZero)
// x == 6.0
// Equivalent to the C 'ceil' function:
var y = 6.5
y.round(.up)
// y == 7.0
// Equivalent to the C 'floor' function:
var z = 6.5
z.round(.down)
// z == 6.0
솔루션 2
extension Numeric {
private func _precision(number: NSNumber, formatter: NumberFormatter) -> Self? {
if let formatedNumString = formatter.string(from: number),
let formatedNum = formatter.number(from: formatedNumString) {
return formatedNum as? Self
}
return nil
}
private func toNSNumber() -> NSNumber? {
if let num = self as? NSNumber { return num }
guard let string = self as? String, let double = Double(string) else { return nil }
return NSNumber(value: double)
}
func precision(_ minimumFractionDigits: Int,
roundingMode: NumberFormatter.RoundingMode = NumberFormatter.RoundingMode.halfUp) -> Self? {
guard let number = toNSNumber() else { return nil }
let formatter = NumberFormatter()
formatter.minimumFractionDigits = minimumFractionDigits
formatter.roundingMode = roundingMode
return _precision(number: number, formatter: formatter)
}
func precision(with numberFormatter: NumberFormatter) -> String? {
guard let number = toNSNumber() else { return nil }
return numberFormatter.string(from: number)
}
}
사용.
_ = 123.44.precision(2)
_ = 123.44.precision(3, roundingMode: .up)
let numberFormatter = NumberFormatter()
numberFormatter.minimumFractionDigits = 1
numberFormatter.groupingSeparator = " "
let num = 222.3333
_ = num.precision(2)
전체샘플
func option1<T: Numeric>(value: T, numerFormatter: NumberFormatter? = nil) {
print("Type: \(type(of: value))")
print("Original Value: \(value)")
let value1 = value.precision(2)
print("value1 = \(value1 != nil ? "\(value1!)" : "nil")")
let value2 = value.precision(5)
print("value2 = \(value2 != nil ? "\(value2!)" : "nil")")
if let value1 = value1, let value2 = value2 {
print("value1 + value2 = \(value1 + value2)")
}
print("")
}
func option2<T: Numeric>(value: T, numberFormatter: NumberFormatter) {
print("Type: \(type(of: value))")
print("Original Value: \(value)")
let value1 = value.precision(with: numberFormatter)
print("formated value = \(value1 != nil ? "\(value1!)" : "nil")\n")
}
func test(with double: Double) {
print("===========================\nTest with: \(double)\n")
let float = Float(double)
let float32 = Float32(double)
let float64 = Float64(double)
let float80 = Float80(double)
let cgfloat = CGFloat(double)
// Exapmle 1
print("-- Option1\n")
option1(value: double)
option1(value: float)
option1(value: float32)
option1(value: float64)
option1(value: float80)
option1(value: cgfloat)
// Exapmle 2
let numberFormatter = NumberFormatter()
numberFormatter.formatterBehavior = .behavior10_4
numberFormatter.minimumIntegerDigits = 1
numberFormatter.minimumFractionDigits = 4
numberFormatter.maximumFractionDigits = 9
numberFormatter.usesGroupingSeparator = true
numberFormatter.groupingSeparator = " "
numberFormatter.groupingSize = 3
print("-- Option 2\n")
option2(value: double, numberFormatter: numberFormatter)
option2(value: float, numberFormatter: numberFormatter)
option2(value: float32, numberFormatter: numberFormatter)
option2(value: float64, numberFormatter: numberFormatter)
option2(value: float80, numberFormatter: numberFormatter)
option2(value: cgfloat, numberFormatter: numberFormatter)
}
test(with: 123.22)
test(with: 1234567890987654321.0987654321)
산출량
===========================
Test with: 123.22
-- Option1
Type: Double
Original Value: 123.22
value1 = 123.22
value2 = 123.22
value1 + value2 = 246.44
Type: Float
Original Value: 123.22
value1 = nil
value2 = nil
Type: Float
Original Value: 123.22
value1 = nil
value2 = nil
Type: Double
Original Value: 123.22
value1 = 123.22
value2 = 123.22
value1 + value2 = 246.44
Type: Float80
Original Value: 123.21999999999999886
value1 = nil
value2 = nil
Type: CGFloat
Original Value: 123.22
value1 = 123.22
value2 = 123.22
value1 + value2 = 246.44
-- Option 2
Type: Double
Original Value: 123.22
formatted value = 123.2200
Type: Float
Original Value: 123.22
formatted value = 123.220001221
Type: Float
Original Value: 123.22
formatted value = 123.220001221
Type: Double
Original Value: 123.22
formatted value = 123.2200
Type: Float80
Original Value: 123.21999999999999886
formatted value = nil
Type: CGFloat
Original Value: 123.22
formatted value = 123.2200
===========================
Test with: 1.2345678909876544e+18
-- Option1
Type: Double
Original Value: 1.2345678909876544e+18
value1 = 1.23456789098765e+18
value2 = 1.23456789098765e+18
value1 + value2 = 2.4691357819753e+18
Type: Float
Original Value: 1.234568e+18
value1 = nil
value2 = nil
Type: Float
Original Value: 1.234568e+18
value1 = nil
value2 = nil
Type: Double
Original Value: 1.2345678909876544e+18
value1 = 1.23456789098765e+18
value2 = 1.23456789098765e+18
value1 + value2 = 2.4691357819753e+18
Type: Float80
Original Value: 1234567890987654400.0
value1 = nil
value2 = nil
Type: CGFloat
Original Value: 1.2345678909876544e+18
value1 = 1.23456789098765e+18
value2 = 1.23456789098765e+18
value1 + value2 = 2.4691357819753e+18
-- Option 2
Type: Double
Original Value: 1.2345678909876544e+18
formatted value = 1 234 567 890 987 650 000.0000
Type: Float
Original Value: 1.234568e+18
formatted value = 1 234 567 939 550 610 000.0000
Type: Float
Original Value: 1.234568e+18
formatted value = 1 234 567 939 550 610 000.0000
Type: Double
Original Value: 1.2345678909876544e+18
formatted value = 1 234 567 890 987 650 000.0000
Type: Float80
Original Value: 1234567890987654400.0
formatted value = nil
Type: CGFloat
Original Value: 1.2345678909876544e+18
formatted value = 1 234 567 890 987 650 000.0000
스위프트 4
let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
@ 기호 없이도 Swift의 NSLog를 Objective-C에서와 같이 사용할 수 있습니다.
NSLog("%.02f %.02f %.02f", r, g, b)
편집: 오랜만에 Swift와 작업을 해보니 이 변형도 추가하고 싶습니다.
var r=1.2
var g=1.3
var b=1.4
NSLog("\(r) \(g) \(b)")
출력:
2014-12-07 21:00:42.128 MyApp[1626:60b] 1.2 1.3 1.4
extension Double {
func formatWithDecimalPlaces(decimalPlaces: Int) -> Double {
let formattedString = NSString(format: "%.\(decimalPlaces)f", self) as String
return Double(formattedString)!
}
}
1.3333.formatWithDecimalPlaces(2)
지금까지 가장 많은 표를 받은 답변은 NSString 방법에 의존하며 Foundation을 가져왔어야 합니다.
그래도 NSLog에 액세스할 수 있습니다.
따라서 Swift에서 NSLog를 계속 사용하는 방법을 묻는 질문에 대한 대답은 다음과 같습니다.
import Foundation
//It will more help, by specify how much decimal Point you want.
let decimalPoint = 2
let floatAmount = 1.10001
let amountValue = String(format: "%0.*f", decimalPoint, floatAmount)
여기서 "순수한" 신속한 해결책
var d = 1.234567
operator infix ~> {}
@infix func ~> (left: Double, right: Int) -> String {
if right == 0 {
return "\(Int(left))"
}
var k = 1.0
for i in 1..right+1 {
k = 10.0 * k
}
let n = Double(Int(left*k)) / Double(k)
return "\(n)"
}
println("\(d~>2)")
println("\(d~>1)")
println("\(d~>0)")
연장의 힘
extension Double {
var asNumber:String {
if self >= 0 {
var formatter = NSNumberFormatter()
formatter.numberStyle = .NoStyle
formatter.percentSymbol = ""
formatter.maximumFractionDigits = 1
return "\(formatter.stringFromNumber(self)!)"
}
return ""
}
}
let velocity:Float = 12.32982342034
println("The velocity is \(velocity.toNumber)")
출력: 속도는 12.3입니다.
타이핑 방법 감소:
func fprint(format: String, _ args: CVarArgType...) {
print(NSString(format: format, arguments: getVaList(args)))
}
위의 많은 좋은 답변들이지만, 때때로 패턴이 "%3f" 종류의 헛소리보다 더 적절합니다.다음은 숫자를 사용한 제 설명입니다.스위프트 3의 포맷터.
extension Double {
func format(_ pattern: String) -> String {
let formatter = NumberFormatter()
formatter.format = pattern
return formatter.string(from: NSNumber(value: self))!
}
}
let n1 = 0.350, n2 = 0.355
print(n1.format("0.00#")) // 0.35
print(n2.format("0.00#")) // 0.355
여기서 저는 항상 2자리 숫자를 보여주기를 원했지만, 0이 아닐 때만 세 번째 숫자를 보여주기를 원했습니다.
Double 및 CGFloat 유형의 확장은 어떻습니까?
extension Double {
func formatted(_ decimalPlaces: Int?) -> String {
let theDecimalPlaces : Int
if decimalPlaces != nil {
theDecimalPlaces = decimalPlaces!
}
else {
theDecimalPlaces = 2
}
let theNumberFormatter = NumberFormatter()
theNumberFormatter.formatterBehavior = .behavior10_4
theNumberFormatter.minimumIntegerDigits = 1
theNumberFormatter.minimumFractionDigits = 1
theNumberFormatter.maximumFractionDigits = theDecimalPlaces
theNumberFormatter.usesGroupingSeparator = true
theNumberFormatter.groupingSeparator = " "
theNumberFormatter.groupingSize = 3
if let theResult = theNumberFormatter.string(from: NSNumber(value:self)) {
return theResult
}
else {
return "\(self)"
}
}
}
용도:
let aNumber: Double = 112465848348508.458758344
Swift.print("The number: \(aNumber.formatted(2))")
프린트: 112465 848 348 508.46
이러한 방법으로 연산자를 만들 수도 있습니다.
operator infix <- {}
func <- (format: String, args:[CVarArg]) -> String {
return String(format: format, arguments: args)
}
let str = "%d %.1f" <- [1453, 1.123]
반올림 포함:
extension Float
{
func format(f: String) -> String
{
return NSString(format: "%\(f)f", self)
}
mutating func roundTo(f: String)
{
self = NSString(format: "%\(f)f", self).floatValue
}
}
extension Double
{
func format(f: String) -> String
{
return NSString(format: "%\(f)f", self)
}
mutating func roundTo(f: String)
{
self = NSString(format: "%\(f)f", self).doubleValue
}
}
x = 0.90695652173913
x.roundTo(".2")
println(x) //0.91
아래의 방법을 사용합니다.
let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)
println(output)
Swift 2.1용으로 업데이트된 Vincent Guerci의 루비 / 파이썬 % 연산자 버전:
func %(format:String, args:[CVarArgType]) -> String {
return String(format:format, arguments:args)
}
"Hello %@, This is pi : %.2f" % ["World", M_PI]
Swift 4 Xcode 10 업데이트
extension Double {
var asNumber:String {
if self >= 0 {
let formatter = NumberFormatter()
formatter.numberStyle = .none
formatter.percentSymbol = ""
formatter.maximumFractionDigits = 2
return "\(formatter.string(from: NSNumber(value: self)) ?? "")"
}
return ""
}
}
@infix func ^(left:Double, right: Int) -> NSNumber {
let nf = NSNumberFormatter()
nf.maximumSignificantDigits = Int(right)
return nf.numberFromString(nf.stringFromNumber(left))
}
let r = 0.52264
let g = 0.22643
let b = 0.94837
println("this is a color: \(r^3) \(g^3) \(b^3)")
// this is a color: 0.523 0.226 0.948
소수점 이하 두 자리에 대해서는 잘 모르겠지만 소수점 이하 0으로 플로트를 인쇄할 수 있는 방법이 있습니다. 따라서 2, 3, 3... (참고: 문자열(format:)로 전달하려면 CGFloat을 이중으로 변환해야 합니다. 그렇지 않으면 값이 0으로 표시됩니다.)
func logRect(r: CGRect, _ title: String = "") {
println(String(format: "[ (%.0f, %.0f), (%.0f, %.0f) ] %@",
Double(r.origin.x), Double(r.origin.y), Double(r.size.width), Double(r.size.height), title))
}
Swift2 예: 소수점을 제거하는 Float을 포맷하는 iOS 장치의 화면 너비
print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
추가할 제안이 있는 경우SwiftUI
의LocalizedStringKey.appendInterpolation
하는 방법.DefaultStringInterpolation
다음과 같은 옵션을 사용할 수 있습니다.
print("\(someValue, specifier: "%0.2f")")
이 The Swift Evolution 제안서인 SE-0228이 채택되면 다음과 같이 작성할 수 있습니다.
// Use printf-style format strings:
"The price is $\(cost, format: "%.2f")"
// Use UTS #35 number formats:
"The price is \(cost, format: "¤###,##0.00")"
// Use Foundation.NumberFormatter, or a new type-safe native formatter:
"The price is \(cost, format: moneyFormatter)"
// Mimic String.init(_:radix:uppercase:)
"The checksum is 0x\(checksum, radix: 16)"
그 동안 당신은 당신의 보간 규칙을 확장하여 설정할 수 있습니다.StringInterpolation
프로토콜:
extension String.StringInterpolation {
mutating func appendInterpolation<T: BinaryFloatingPoint>(_ value: T, using style: NumberFormatter.Style, maxFractionDigits: Int? = nil) {
let formatter = NumberFormatter()
formatter.numberStyle = style
if let maxFractionDigits {
formatter.maximumFractionDigits = maxFractionDigits
}
if let value = value as? NSNumber, let result = formatter.string(from: value as NSNumber) {
appendLiteral(result)
}
}
}
그러면 다음과 같이 쓰는 것이 가능해집니다.
print("The value is \(123.456, using: .decimal, maxFractionDigits: 2).")
// The value is 123.46.
또는 다음과 같은 작업을 수행할 수 있습니다.
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: Double, formatted style: FloatingPointFormatStyle<Double>) {
appendLiteral(value.formatted(style))
}
}
print("The value is \(123.456, formatted: .number.precision(.fractionLength(1)))")
// The value is 123.5
언급URL : https://stackoverflow.com/questions/24051314/precision-string-format-specifier-in-swift
'programing' 카테고리의 다른 글
배열에서 빈 요소를 제거하려면 어떻게 해야 합니까? (0) | 2023.05.18 |
---|---|
관계형 데이터베이스에 계층 데이터를 저장하는 옵션은 무엇입니까? (0) | 2023.05.18 |
기본 유형 생성자를 호출하기 전에 VB.NET이 인스턴스 변수를 초기화하도록 강제할 수 있습니까? (0) | 2023.05.13 |
MEF 플러그인 프로젝트에 참조를 추가할 때 경고 아이콘이 표시되는 이유는 무엇입니까? (0) | 2023.05.13 |
Angular 2에서 구성 요소의 재렌더링을 강제하는 방법은 무엇입니까? (0) | 2023.05.13 |