Especificador de formato de cadeia de precisão no Swift

395

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!

user3524868
fonte

Respostas:

277

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.

Anton Tcholakov
fonte
76
Isso é desnecessariamente complicado. A resposta da realityone funciona e é muito mais concisa.
Steven Marlowe
9
Claro, se você estiver usando apenas uma vez. Mas se você quiser ter mais opções de formatação usando a interpolação de strings (que é muito mais legível), poderá colocar todas as extensões de formatação em um arquivo em outro lugar e referenciá-lo em todo o seu projeto. Obviamente, idealmente, a Apple deve fornecer a biblioteca de formatação.
Anton Tcholakov
2
Esta solução não funcionará no Swift 1.2 sem converter o resultado em String.
Ibesora 10/04/2015
Agradável, mas não Swift 2 Friend.
Última atualização
798

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))
realityone
fonte
9
println(String(format: "a float number: %.5f", 1.0321))
Zaph
78
Eu acredito que esta é uma resposta melhor do que a resposta aceita. É muito mais próximo do estilo c padrão, printfsem a necessidade de escrever extensões separadas.
Keith Morris
9
Não se esqueça da "importação Foundation" na parte superior do arquivo.
Chris Gregg
3
Isso é melhor do que a resposta aceita, mas ainda está usando os métodos Foundation (em ponte para Swift).
11
Certifique-se deimport Foundation
NaN
125

Eu achei String.localizedStringWithFormatque funcionou muito bem:

Exemplo:

let value: Float = 0.33333
let unit: String = "mph"

yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
Valentin
fonte
A questão não tem nada a ver com unidades de gestão. localizedStringWithFormat é bom, mas não relacionado.
AmitP
Concordo AmitP, foi perguntado antes String (formato: ..., argumentos ...) estava disponível
Valentin
84

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
fatihyildizhan
fonte
Isso não é compilado (usando o 3.0.2 na caixa de areia Swift da IBM):Col 16: 'init' has been renamed to 'init(describing:)'
Peter Dillinger
@ PeterDillinger, você está passando um valor opcional em vez de desembrulhado.
Michael
63

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

Atualização 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)"
    }
}
Donn
fonte
12
Eu gostaria que mais pessoas usassem 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).
Rob
3
A única melhoria que eu gostaria de ver é armazenar o formatador para qualquer número - os NSNumberFormatters são caros de construir.
Kendall Helmstetter Gelner
11
Exatamente o que eu estava procurando! Obrigado
gunjot singh
Eu sei que essa é uma pergunta um tanto antiga, mas 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.
promacuser
44

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, Stringsuporta diretamente o format:inicializador, portanto não há necessidade de usar NSStringe o @infixatributo 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"
David Berry
fonte
onde você encontrou a sintaxe `NSString (format:" formatString ", val) '. Não o vejo no documento iBooks da Apple.
Duncan C
11
É o mesmo que construir rapidamente qualquer objeto objetivo-c. É a versão rápida de[NSString stringWithFormat...
David Berry
Peguei vocês. Ainda não cheguei tão longe no Swift iBook.
Duncan C
IIRC que não estava no Swift iBook. Foi em uma das sessões da WWDC. Interoperabilidade
rápida
2
Se você estava implementando% como no Python, deveria ser o contrário. "% 5.3f"% M_PI
Andy Dent
16

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/

Steyn Viljoen
fonte
Esta é de longe a melhor solução, não entendo como isso não está no topo.
Pjtnt11
7
coisa nitpicky .. 1,500 milhões seria apenas "1,5" e não "1,50"
styler1972
13
import Foundation

extension CGFloat {
    var string1: String {
        return String(format: "%.1f", self)
    }
    var string2: String {
        return String(format: "%.2f", self)
    }
}

Uso

let offset = CGPoint(1.23, 4.56)
print("offset: \(offset.x.string1) x \(offset.y.string1)")
// offset: 1.2 x 4.6
neoneye
fonte
10

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]
Vincent Guerci
fonte
Infelizmente, isso morre no beta 6: erro fatal: não é possível inseguroBitCast entre tipos de tamanhos diferentes.
precisa saber é o seguinte
@binarymochi Com o Beta 6: "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.
Vincent Guerci
Você poderia transformar ',' no operador usado? '@infix func, (…' e escreva suas strings como "Olá% @, este é pi:% .2f", ["você", M_PI])?
19314 Rick
@ Rick não, você não pode, nã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/…
Vincent Guerci
8

Swift 4

let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
onmyway133
fonte
let temp: Float = div * 100 let string = String (formato: "% .2f", localidade: Locale.current, argumentos: temp) está me dando erro. Não é possível converter o valor do tipo 'Flutuar' para o tipo de argumento esperado '[CVarArg]
Chandni
você precisa colocar que 15,123 em uma matriz para torná-lo trabalho
Dorian Roy
3
para mim funciona: deixe string = String (formato: "% .2f", myString)
Grzegorz R. Kulesza
6

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
hol
fonte
6

Detalhes

  • Xcode 9.3, Swift 4.1
  • Xcode 10.2.1 (10E1001), Swift 5

Solução 1

func arredondado () -> duplo

(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"

mutando func round ()

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

Solução 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)
    }
}

Uso

_ = 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)

Amostra completa

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)

Resultado

===========================
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
Vasily Bodnarchuk
fonte
4
extension Double {
  func formatWithDecimalPlaces(decimalPlaces: Int) -> Double {
     let formattedString = NSString(format: "%.\(decimalPlaces)f", self) as String
     return Double(formattedString)!
     }
 }

 1.3333.formatWithDecimalPlaces(2)
Lucas Farah
fonte
3

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

fqdn
fonte
3
//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)
Ravi Kumar
fonte
2

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)")
Christian Dietrich
fonte
2

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

Muhammad Aamir Ali
fonte
2

menos maneira de digitar:

func fprint(format: String, _ args: CVarArgType...) {
    print(NSString(format: format, arguments: getVaList(args)))
}
pico
fonte
1

Você também pode criar um operador dessa maneira

operator infix <- {}

func <- (format: String, args:[CVarArg]) -> String {
    return String(format: format, arguments: args)
}

let str = "%d %.1f" <- [1453, 1.123]
otello
fonte
1

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
ChikabuZ
fonte
1

use o método abaixo

let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)

println(output)
Ramkumar chintala
fonte
1

Uma versão do operador ruby ​​/ python% de Vincent Guerci, atualizada para o Swift 2.1:

func %(format:String, args:[CVarArgType]) -> String {
  return String(format:format, arguments:args)
}

"Hello %@, This is pi : %.2f" % ["World", M_PI]
Paul King
fonte
1

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.

AlexT
fonte
1

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 ""
    }
}
Jason
fonte
1

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

M Wilm
fonte
0
@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
user3778351
fonte
0

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))
}
luz clara
fonte
0

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)))
Gunnar Forsgren - Mobimation
fonte
-1

@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 ...

Stuepfnick
fonte
Obviamente, isso pretende ser um comentário, eu entendo que você precisa de mais espaço para fazer uma observação, e é valioso, mas se você for escrever como uma resposta completa, faça com que seja útil por si só, independentemente; você pode adicionar o código completo, por exemplo, e depois fazer um comentário e agradecer a Christian.
Jaime Gómez
@ Jaime Gómez: Não tenho permissão para comentar a resposta acima. Mas de qualquer maneira, eu tinha alguma interpretação falsa *. Não sei, se vale a pena ser mantido ou deve ser excluído. Obviamente, isso pode ser usado de maneira semelhante apenas para arredondamentos (sem conversão de strings) e pode ser facilmente traduzido para outras linguagens de programação. * Presumi que, com o Double, ele é arredondado para cerca de 8 dígitos, o que, obviamente, foi um erro, porque eu o arredondei com o Float e o converti para o Double acidentalmente.
Stuepfnick
PS: Eu preferiria usar métodos semelhantes mais para arredondar em geral, não para saída de String, então retorne o tipo Double (& método regular?) Nota : Se você arredondar um Float dessa maneira (por exemplo, de um Slider) e o resultado para String it ficará bom, como "0.1", mas se você converter esse Float para Double e depois para String * será: "0.100000001490116", pois o Float não é capaz de armazenar 0.1 exatamente, apenas muito próximo. Eu acho que é o mesmo com Double, apenas com precisão dupla ;) Portanto, sempre converta para Double antes de arredondar, para que seja o mais exato possível e também para String bem.
Stuepfnick
PPS: Obviamente, com o Return Type Double, às vezes é um pouco diferente, ou seja, se você precisar definir um texto para o rótulo, precisará escrever: myLabel.text = "\ (d ~> 2)" em vez de apenas: myLabel. text = d ~> 2 , mas ainda acho que a função é mais prática dessa maneira. (é claro que todo mundo pode fazer, o que eles querem, apenas os meus pensamentos ...)
Stuepfnick
-2

usar

CGFloat 

ou

Float.roundTo(places:2)
Nicson
fonte
11
CGFloat não tem nenhum membro redondo para
Chandni