Ниже показано, как я бы предварительно обрезал число с плавающей запятой до двух десятичных разрядов.
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"
Вы можете определить аналогичные операторы для всех числовых типов, к сожалению, я не нашел способа сделать это с обобщениями.
Swift 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
Посмотрите, как это работает на детской площадке.
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/...
Swift 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
округленная функция (_ rule: 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
мутирующий раунд функции (_ rule: 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 десятичных знака, но только третий, если он не равен нулю.
Обновление 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 ""
}
}
Как насчет расширений для типов 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, чтобы передать в строку (формат :) или он будет видеть значение ноль)
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)))
@ Кристиан Дитрих:
вместо:
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 и round на roundf.
Обновление: я обнаружил, что наиболее целесообразно использовать тип возврата Double вместо String. Он работает так же для вывода String, то есть:
println("Pi is roughly \(3.1415926 ~> 3)")
печатает: Pi примерно 3,142.
Таким образом, вы можете использовать его для Strings (вы можете даже написать: println (d ~> 2)), но дополнительно вы также можете использовать его для прямого округления значений, то есть:
d = Double(slider.value) ~> 2
или что вам нужно ...