스위프트의 정밀 문자열 형식 지정자
아래는 이전에 소수점을 소수점 이하 두 자리로 자른 방법입니다.
NSLog(@" %.02f %.02f %.02f", r, g, b);
문서와 eBook을 확인했지만 확인할 수 없었습니다. 감사!
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
나는 이것이 포맷 작업을 데이터 유형에 직접 연결하는 가장 신속한 솔루션이라고 생각합니다. 어딘가에 서식 작업 라이브러리가 내장되어 있거나 곧 출시 될 수 있습니다. 언어는 아직 베타 버전입니다.
간단한 방법은 다음과 같습니다.
import Foundation // required for String(format: _, _)
print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
나는 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"
모든 숫자 유형에 대해 유사한 연산자를 정의 할 수 있지만 불행하게도 제네릭으로 수행하는 방법을 찾지 못했습니다.
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
왜 그렇게 복잡하게 만드나요? 대신 이것을 사용할 수 있습니다 :
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
놀이터에서 작동하는지 확인하십시오.
추신 : 솔루션 : http://rrike.sh/xcode/rounding-various-decimal-places-swift/
더 우아하고 일반적인 솔루션은 루비 / 파이썬 %
연산자 를 다시 작성하는 것입니다 .
// 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]
스위프트 4
let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
세부
- Xcode 9.3, 스위프트 4.1
- Xcode 10.2.1 (10E1001), 스위프트 5
해결책 1
(5.2).rounded()
// 5.0
(5.5).rounded()
// 6.0
(-5.2).rounded()
// -5.0
(-5.5).rounded()
// -6.0
func rounded (_ rule : FloatingPointRoundingRule)-> 이중
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
펑크 라운드 돌연변이 (_ 규칙 : FloatingPointRoundingRule)
// 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
@ 기호없이 Objective-C에서와 같이 Swift에서 NSLog를 계속 사용할 수 있습니다.
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)))
}
이런 식으로 연산자를 만들 수도 있습니다
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]
위의 좋은 대답이 많지만 때때로 패턴이 "% .3f"종류의 gobbledygook보다 더 적합합니다. Swift 3에서 NumberFormatter를 사용하는 방법은 다음과 같습니다.
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 개의 소수점을 표시하고 싶었지만 3이 0이 아닌 경우에만 표시했습니다.
스위프트 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 ""
}
}
이중 및 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))")
인쇄 : 112 465 848 348 508.46
@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
내가 모르는 두 소수점하지만, 여기에 내가 그 2 곳, 3 곳 ... 수 있습니다 치지 있도록, 제로 소수점으로 수레를 인쇄 할 수있는 방법 (참고 : 당신이 해야 두 번에 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)))
@ 크리스찬 디트리히 :
대신에:
var k = 1.0
for i in 1...right+1 {
k = 10.0 * k
}
let n = Double(Int(left*k)) / Double(k)
return "\(n)"
그것은 또한 될 수 있습니다 :
let k = pow(10.0, Double(right))
let n = Double(Int(left*k)) / k
return "\(n)"
[수정 :] 혼란을 드려 죄송합니다 *-물론 Doubles에서도 작동합니다. 가장 실용적인 방법은 (숫자를 반올림하고 자르지 않으려는 경우) 다음과 같습니다.
infix operator ~> {}
func ~> (left: Double, right: Int) -> Double {
if right <= 0 {
return round(left)
}
let k = pow(10.0, Double(right))
return round(left*k) / k
}
Float 전용의 경우 Double을 Float로 바꾸고 pow를 powf로, round를 roundf로 바꾸십시오.
업데이트 : String 대신 반환 유형 Double을 사용하는 것이 가장 실용적인 것으로 나타났습니다. 문자열 출력에서도 동일하게 작동합니다.
println("Pi is roughly \(3.1415926 ~> 3)")
인쇄 : Pi는 약 3.142
이므로 문자열과 같은 방식으로 사용할 수 있습니다 (여전히 println (d ~> 2)라고 쓸 수도 있음). 또한 값을 직접 반올림하는 데 사용할 수도 있습니다.
d = Double(slider.value) ~> 2
또는 필요한 모든 것…
사용하다
CGFloat
또는
Float.roundTo(places:2)
참고 URL : https://stackoverflow.com/questions/24051314/precision-string-format-specifier-in-swift
'Programing' 카테고리의 다른 글
Bash의 삼항 연산자 (? :) (0) | 2020.02.27 |
---|---|
파이썬에서 문자열에서 숫자를 추출하는 방법은 무엇입니까? (0) | 2020.02.27 |
WCF와 ASMX 웹 서비스의 차이점은 무엇입니까? (0) | 2020.02.27 |
SQLAlchemy : flush ()와 commit ()의 차이점은 무엇입니까? (0) | 2020.02.27 |
PDF를 텍스트로 변환하는 Python 모듈 (0) | 2020.02.27 |