Нижче описано, як я б попередньо обрізав поплавок до двох знаків після коми
NSLog(@" %.02f %.02f %.02f", r, g, b);
Я перевірив документи та електронну книгу, але не зміг це зрозуміти. Дякую!
Нижче описано, як я б попередньо обрізав поплавок до двох знаків після коми
NSLog(@" %.02f %.02f %.02f", r, g, b);
Я перевірив документи та електронну книгу, але не зміг це зрозуміти. Дякую!
Відповіді:
Моє найкраще рішення досі, виходячи з відповіді Девіда :
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, пов’язуючи операції з форматування безпосередньо до типу даних. Цілком може бути, що десь є вбудована бібліотека операцій форматування, а може вона скоро вийде. Майте на увазі, що мова все ще знаходиться в бета-версії.
простий спосіб:
import Foundation // required for String(format: _, _)
print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
println(String(format: "a float number: %.5f", 1.0321))
printf
без необхідності писати окремі розширення.
import Foundation
Я виявив, 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
Col 16: 'init' has been renamed to 'init(describing:)'
Більшість відповідей тут справедливі. Однак, якщо ви будете часто форматувати число, подумайте про розширення класу 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
extension Float {
func string(fractionDigits:Int) -> String {
let formatter = NumberFormatter()
formatter.minimumFractionDigits = fractionDigits
formatter.maximumFractionDigits = fractionDigits
return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
}
}
NSNumberFormatter
, як ця відповідь. Інші відповіді з високою оцінкою просто не відображають налаштування місцевості пристрою (наприклад, у деяких місцевостях вони використовують коми через десяткове місце; це відображає це; інші відповіді не відповідають).
NSNumberFormatter
ініціалізувати досить повільно. Якщо можливо, це допомагає визначити його та повторно використовувати його. Це сказав, що я читаю це питання, тому що це неможливо в моєму випадку.
Ви не можете зробити це (поки) за допомогою інтерполяції рядків. Найбільша ставка все ще буде форматуванням NSString:
println(NSString(format:"%.2f", sqrt(2.0)))
Екстраполюючи з python, здається, що розумним синтаксисом може бути:
@infix func % (value:Double, format:String) -> String {
return NSString(format:format, value)
}
Що потім дозволяє використовувати їх як:
M_PI % "%5.3f" // "3.142"
Ви можете визначити подібні оператори для всіх числових типів, на жаль, я не знайшов способу зробити це за допомогою дженериків.
Швидке оновлення 5
Як мінімум, Swift 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"
[NSString stringWithFormat...
Чому це зробити так складно? Ви можете використовувати це замість:
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
Більш елегантне і загальне рішення - переписати %
оператор ruby / python :
// 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]
"Hello %@, This is pi : %.2f" % ["World", M_PI]
працює, але дивно "%@ %@" % ["Hello", "World"]
піднімає can't unsafeBitCast
... Здогадайтесь, що буде виправлено у наступній версії.
,
не є дійсним оператором символів на Swift та більшості мов. І imo, краще використовувати %
оператор, який вже існує іншими мовами. Дивіться developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Швидкий 4
let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
Ви все ще можете використовувати NSLog як у Swift, так і в 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
(5.2).rounded()
// 5.0
(5.5).rounded()
// 6.0
(-5.2).rounded()
// -5.0
(-5.5).rounded()
// -6.0
func округлий (_ правило: FloatingPointRoundingRule) -> Double
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
вимкнення функції func round (_ правило: 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
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
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.
Тому я думаю, що відповідь на питання, якщо ви запитуєте, як продовжувати використовувати NSLog в Swift, - це просто:
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
Також з округленням:
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)
Вище хороших відповідей вище, але іноді візерунок є більш доцільним, ніж "% .3f" сорт гоблі. Ось мій досвід використання NumberFormatter у Swift 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 десяткові знаки, але третій, лише якщо це не було нуля.
Швидке оновлення 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 ""
}
}
Як щодо розширень для типів 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))")
принти: 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 в Double, щоб пройти до String (формат :) або він побачить значення нуля)
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: Ширина екрана пристрою iOS, що форматує Float, видаляючи десятковий
print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
@Christian Dietrich:
замість:
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)"
[виправлення:] Вибачте за плутанину * - Звичайно, це працює з дублями. Я думаю, що найпрактичніше (якщо ви хочете, щоб цифри були округленими, а не відрізаними), це було б щось подібне:
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 і круглий на Roundf.
Оновлення: я виявив, що найправильніше використовувати тип повернення Double замість String. Він працює так само і для String output, тобто:
println("Pi is roughly \(3.1415926 ~> 3)")
друкує: Pi становить приблизно 3.142,
тож ви можете використовувати його так само, як і для Strings (ви навіть можете ще написати: println (d ~> 2)), але додатково ви також можете використовувати його для прямого округлення значень, тобто:
d = Double(slider.value) ~> 2
або все, що вам потрібно ...