Abaixo está como eu teria previamente truncado um float com duas casas decimais
NSLog(@" %.02f %.02f %.02f", r, g, b);
Verifiquei os documentos e o eBook, mas não consegui descobrir. Obrigado!
Abaixo está como eu teria previamente truncado um float com duas casas decimais
NSLog(@" %.02f %.02f %.02f", r, g, b);
Verifiquei os documentos e o eBook, mas não consegui descobrir. Obrigado!
Respostas:
Minha melhor solução até agora, seguindo a resposta de 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
Eu acho que essa é a solução mais rápida, vinculando as operações de formatação diretamente ao tipo de dados. Pode ser que exista uma biblioteca interna de operações de formatação em algum lugar ou talvez ela seja lançada em breve. Lembre-se de que o idioma ainda está na versão beta.
uma maneira simples é:
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
sem a necessidade de escrever extensões separadas.
import Foundation
Eu achei String.localizedStringWithFormat
que funcionou muito bem:
Exemplo:
let value: Float = 0.33333
let unit: String = "mph"
yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
Essa é uma maneira muito rápida e simples que não precisa de solução complexa.
let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
Col 16: 'init' has been renamed to 'init(describing:)'
A maioria das respostas aqui são válidas. No entanto, caso você formate o número com frequência, considere estender a classe Float para adicionar um método que retorne uma string formatada. Veja o código de exemplo abaixo. Este atinge o mesmo objetivo usando um formatador e extensão de número.
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))")
O console mostra:
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
, como esta resposta. As outras respostas altamente votadas simplesmente não refletem as configurações de localidade do dispositivo (por exemplo, em algumas localidades, elas usam vírgula para uma casa decimal; isso reflete isso; outras respostas não).
NSNumberFormatter
é bastante lenta para inicializar. Se possível, ajuda a definir um e reutilizá-lo. Dito isto, estou aqui lendo esta pergunta, porque isso não é possível no meu caso.
Você ainda não pode fazer isso com interpolação de strings. Sua melhor aposta ainda será a formatação NSString:
println(NSString(format:"%.2f", sqrt(2.0)))
Extrapolando do python, parece que uma sintaxe razoável pode ser:
@infix func % (value:Double, format:String) -> String {
return NSString(format:format, value)
}
O que permite que você os use como:
M_PI % "%5.3f" // "3.142"
Você pode definir operadores semelhantes para todos os tipos numéricos, infelizmente não encontrei uma maneira de fazer isso com genéricos.
Atualização do Swift 5
Pelo menos no Swift 5, String
suporta diretamente o format:
inicializador, portanto não há necessidade de usar NSString
e o @infix
atributo não é mais necessário, o que significa que as amostras acima devem ser escritas como:
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...
Por que torná-lo tão complicado? Você pode usar isso:
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
Veja como funciona no Playground.
PS: Solução de: http://rrike.sh/xcode/rounding-various-decimal-places-swift/
Uma solução mais elegante e genérica é reescrever o %
operador 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]
funciona, mas estranhamente "%@ %@" % ["Hello", "World"]
aumenta can't unsafeBitCast
... Acho que isso será corrigido na próxima versão.
,
é um operador de caractere válido, no Swift e na maioria dos idiomas. Além disso, é melhor usar o %
operador que já existe em outros idiomas. Veja developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Swift 4
let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
Você ainda pode usar o NSLog no Swift como no Objective-C, apenas sem o sinal @.
NSLog("%.02f %.02f %.02f", r, g, b)
Edit: Depois de trabalhar com Swift há algum tempo, eu gostaria de adicionar também essa variação
var r=1.2
var g=1.3
var b=1.4
NSLog("\(r) \(g) \(b)")
Resultado:
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 arredondado (_ regra: FloatingPointRoundingRule) -> Duplo
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
mutando func round (_ regra: 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)
As respostas dadas até o momento e que receberam mais votos dependem dos métodos NSString e exigirão que você tenha importado o Foundation.
Tendo feito isso, no entanto, você ainda tem acesso ao NSLog.
Então eu acho que a resposta para a pergunta, se você está perguntando como continuar usando o NSLog no Swift, é simplesmente:
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)
aqui uma solução rápida "pura"
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)")
Poder de extensão
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)")
Saída: A velocidade é 12,3
Também com arredondamento:
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
use o método abaixo
let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)
println(output)
Muitas boas respostas acima, mas às vezes um padrão é mais apropriado do que o tipo "% .3f" de palavrões. Aqui está minha opinião usando um NumberFormatter no 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
Aqui, eu queria que duas casas decimais fossem sempre mostradas, mas a terceira apenas se não fosse zero.
Swift 4 Xcode 10 Atualizar
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 ""
}
}
E as extensões nos tipos Double e 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)"
}
}
}
Uso:
let aNumber: Double = 112465848348508.458758344
Swift.print("The number: \(aNumber.formatted(2))")
impressões: 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
Eu não sei sobre duas casas decimais, mas aqui está como você pode imprimir carros alegóricos com zero casas decimais, então eu imagino que podem ser 2 casas, 3 casas ... (Nota: você deve converter CGFloat em Double para passar para String (formato :) ou verá um valor zero)
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))
}
Exemplo Swift2: largura da tela do dispositivo iOS formatando o Float removendo o decimal
print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
@Christian Dietrich:
ao invés de:
var k = 1.0
for i in 1...right+1 {
k = 10.0 * k
}
let n = Double(Int(left*k)) / Double(k)
return "\(n)"
também pode ser:
let k = pow(10.0, Double(right))
let n = Double(Int(left*k)) / k
return "\(n)"
[correção:] Desculpe pela confusão * - Claro que isso funciona com Doubles. Eu acho que, mais prático (se você quiser que os dígitos sejam arredondados, não cortados), seria algo assim:
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
}
Apenas para Float, basta substituir Double por Float, pow com powf e arredondar com roundf.
Atualização: achei mais prático usar o tipo de retorno Double em vez de String. Funciona da mesma forma para a saída String, ou seja:
println("Pi is roughly \(3.1415926 ~> 3)")
prints: Pi é aproximadamente 3.142
Portanto, você pode usá-lo da mesma maneira para Strings (você ainda pode escrever: println (d ~> 2)), mas também pode usá-lo para arredondar valores diretamente, ou seja:
d = Double(slider.value) ~> 2
ou o que você precisar ...