Especificador de formato de cadena de precisión en Swift

395

A continuación se muestra cómo hubiera truncado previamente un flotador a dos decimales

NSLog(@" %.02f %.02f %.02f", r, g, b);

Revisé los documentos y el libro electrónico, pero no he podido resolverlo. ¡Gracias!

usuario3524868
fuente

Respuestas:

277

Mi mejor solución hasta ahora, siguiendo la respuesta 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

Creo que esta es la solución más rápida, vinculando las operaciones de formateo directamente al tipo de datos. Es muy posible que haya una biblioteca incorporada de operaciones de formateo en algún lugar, o tal vez se lance pronto. Tenga en cuenta que el idioma aún está en beta.

Anton Tcholakov
fuente
76
Esto es innecesariamente complicado. La respuesta de realityone funciona y es mucho más concisa.
Steven Marlowe
99
Claro, si solo lo estás usando una vez. Pero si desea tener más opciones de formato utilizando la interpolación de cadenas (que es mucho más legible), puede colocar todas las extensiones de formato en un archivo en otro lugar y hacer referencia a él en todo su proyecto. Por supuesto, idealmente Apple debería proporcionar la biblioteca de formato.
Anton Tcholakov
2
Esta solución no funcionará en Swift 1.2 sin lanzar el resultado a String.
ibesora
Bonito, pero no Swift 2 Friend.
LastMove
798

una manera simple es:

import Foundation // required for String(format: _, _)

print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
realityone
fuente
99
println(String(format: "a float number: %.5f", 1.0321))
zaph
78
Creo que esta es una mejor respuesta que la respuesta aceptada. Está mucho más cerca del estilo c estándar printfsin tener que escribir extensiones separadas.
Keith Morris
99
No olvide la "importación de la Fundación" en la parte superior del archivo.
Chris Gregg
3
Esto es mejor que la respuesta aceptada, pero sigue utilizando los métodos de Foundation (puenteados a Swift).
1
Asegúrese deimport Foundation
NaN
125

Me pareció String.localizedStringWithFormatque funciona bastante bien:

Ejemplo:

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

yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
Valentin
fuente
La pregunta no tiene nada que ver con unidades de manejo. localizedStringWithFormat es agradable, pero no está relacionado.
AmitP
Estoy de acuerdo con AmitP, se le preguntó antes de que String (formato: ..., argumentos: ...) estuviera disponible
Valentin
84

Esta es una manera muy rápida y simple que no necesita una solución compleja.

let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
fatihyildizhan
fuente
Esto no se compila (usando 3.0.2 en la caja de arena Swift de IBM):Col 16: 'init' has been renamed to 'init(describing:)'
Peter Dillinger el
@PeterDillinger está pasando un valor opcional en lugar de un valor sin envolver.
Michael
63

La mayoría de las respuestas aquí son válidas. Sin embargo, en caso de que formatee el número con frecuencia, considere extender la clase Float para agregar un método que devuelva una cadena con formato. Vea el código de ejemplo a continuación. Este logra el mismo objetivo mediante el uso de un formateador de números y extensión.

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

La consola muestra:

The velocity is 12.33
The velocity is 12.3

Actualización de 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
fuente
12
Desearía que más personas usaran NSNumberFormatter, como esta respuesta. Las otras respuestas altamente votadas simplemente no reflejan la configuración regional del dispositivo (por ejemplo, en algunas localidades, usan una coma para un lugar decimal; esto refleja eso; otras respuestas no).
Rob
3
La única mejora que me gustaría ver es almacenar el formateador para cualquier número dado: los NSNumberFormatters son caros de construir.
Kendall Helmstetter Gelner
1
¡Exactamente lo que estaba buscando! Gracias
gunjot singh
Sé que esta es una pregunta algo antigua, pero NSNumberFormatteres bastante lenta de inicializar. Si es posible, ayuda a definir uno y reutilizarlo. Dicho esto, estoy aquí leyendo esta pregunta porque eso no es posible en mi caso.
Promacuser
44

No puede hacerlo (todavía) con la interpolación de cadenas. Su mejor apuesta seguirá siendo el formato NSString:

println(NSString(format:"%.2f", sqrt(2.0)))

Extrapolando desde Python, parece que una sintaxis razonable podría ser:

@infix func % (value:Double, format:String) -> String {
    return NSString(format:format, value)
}

Lo que luego te permite usarlos como:

M_PI % "%5.3f"                // "3.142"

Puede definir operadores similares para todos los tipos numéricos, desafortunadamente no he encontrado una manera de hacerlo con genéricos.

Actualización de Swift 5

Al menos a partir de Swift 5, Stringadmite directamente el format:inicializador, por lo que no es necesario usarlo NSStringy el @infixatributo ya no es necesario, lo que significa que las muestras anteriores deben escribirse 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
fuente
¿Dónde encontró esa sintaxis `NSString (formato:" formatString ", val) '. No lo veo en el documento de iBooks de Apple.
Duncan C
1
Es lo mismo que construir cualquier objeto objetivo-c de forma rápida. Es la versión rápida de[NSString stringWithFormat...
David Berry
Gotcha Todavía no he llegado tan lejos en el Swift iBook.
Duncan C
IIRC que no estaba en el Swift iBook. Fue en una de las sesiones de la WWDC. Interoperabilidad rápida en profundidad
ahruss
2
Si estaba implementando% como en Python, debería ser al revés. "% 5.3f"% M_PI
Andy Dent
16

¿Por qué hacerlo tan complicado? Puedes usar esto en su lugar:

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

Véalo funcionar en Playground.

PD: Solución de: http://rrike.sh/xcode/rounding-various-decimal-places-swift/

Steyn Viljoen
fuente
Esta es, de lejos, la mejor solución, no entiendo cómo esto no está en la cima.
pjtnt11
77
cosa puntiaguda .. 1.500000000 solo sería "1.5" y no "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
fuente
10

Una solución más elegante y genérica es reescribir el %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
fuente
Lamentablemente, esto muere en la versión beta 6: error fatal: no se puede insegurar BitCast entre tipos de diferentes tamaños.
binarymochi
Con @binarymochi Beta 6: "Hello %@, This is pi : %.2f" % ["World", M_PI]funciona, pero extrañamente "%@ %@" % ["Hello", "World"]aumento can't unsafeBitCast... supongo que será corregido en la próxima versión.
Vincent Guerci
¿Podría hacer ',' en el operador utilizado? '@infix func, (...', y luego escribe tus cadenas como "Hola% @, esto es pi:% .2f", ["you", M_PI])?
Rick
@Rick no, no puedes, no ,es un operador de caracteres válido, en Swift y la mayoría de los idiomas. E imo, es mejor usar el %operador que ya existe en otros idiomas. Ver 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
fuente
let temp: Float = div * 100 let string = String (formato: "% .2f", locale: Locale.current, argumentos: temp) me está dando un error. No se puede convertir el valor del tipo 'Float' al tipo de argumento esperado '[CVarArg]
Chandni
necesitas poner ese 15.123 en una matriz para que funcione
Dorian Roy
3
para mí funciona: let string = String (formato: "% .2f", myString)
Grzegorz R. Kulesza
6

Todavía puede usar NSLog en Swift como en Objective-C solo sin el signo @.

NSLog("%.02f %.02f %.02f", r, g, b)

Editar: después de trabajar con Swift desde hace un tiempo, me gustaría agregar también esta variación

    var r=1.2
    var g=1.3
    var b=1.4
    NSLog("\(r) \(g) \(b)")

Salida:

2014-12-07 21:00:42.128 MyApp[1626:60b] 1.2 1.3 1.4
hol
fuente
6

Detalles

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

Solución 1

func redondeado () -> Doble

(5.2).rounded()
// 5.0
(5.5).rounded()
// 6.0
(-5.2).rounded()
// -5.0
(-5.5).rounded()
// -6.0

func redondeado (_ regla: FloatingPointRoundingRule) -> Doble

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"

función de mutación redonda ()

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

función de mutación redonda (_ regla: 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

Solución 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)

Muestra 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)

Salida

===========================
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
fuente
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
fuente
3

Las respuestas dadas hasta ahora que han recibido la mayor cantidad de votos dependen de los métodos de NSString y requerirán que haya importado Foundation.

Sin embargo, después de eso, todavía tiene acceso a NSLog.

Entonces, creo que la respuesta a la pregunta, si está preguntando cómo continuar usando NSLog en Swift, es simplemente:

import Foundation

fqdn
fuente
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
fuente
2

aquí una solución 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
fuente
2

Poder de extensión

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

Salida: la velocidad es 12.3

Muhammad Aamir Ali
fuente
2

menos forma de escribir:

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

También puede crear un operador de esta manera

operator infix <- {}

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

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

También con redondeo:

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
fuente
1

utilice el siguiente método

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

println(output)
Ramkumar chintala
fuente
1

Una versión del operador% ruby ​​/ python de Vincent Guerci, actualizada para 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
fuente
1

Muchas buenas respuestas anteriores, pero a veces un patrón es más apropiado que el tipo "% .3f" de gobbledygook. Aquí está mi opinión usando un NumberFormatter en 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

Aquí quería que siempre se mostraran 2 decimales, pero el tercero solo si no era cero.

AlexT
fuente
1

Actualización de 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 ""
    }
}
Jason
fuente
1

¿Qué pasa con las extensiones en los tipos Double y 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))")

impresiones: 112 465 848 348 508.46

M Wilm
fuente
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
usuario3778351
fuente
0

No sé acerca de dos lugares decimales, pero así es como puede imprimir flotantes con cero lugares decimales, así que me imagino que puede ser 2 lugares, 3, lugares ... (Nota: debe convertir CGFloat a Doble para pasar a cadena (formato :) o verá un valor de cero)

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
fuente
0

Ejemplo de Swift2: ancho de pantalla del dispositivo iOS formateando el flotador eliminando el decimal

print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
Gunnar Forsgren - Mobimation
fuente
-1

@Christian Dietrich:

en vez 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)"

También podría ser:

let k = pow(10.0, Double(right))
let n = Double(Int(left*k)) / k
return "\(n)"

[corrección:] Perdón por la confusión * - Por supuesto, esto funciona con Dobles. Creo que lo más práctico (si quieres que los dígitos se redondeen, no se corten) sería algo así:

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
}

Solo para Flotador, simplemente reemplace Doble con Flotador, pow con powf y redondee con roundf.
Actualización: descubrí que es más práctico usar el tipo de retorno Double en lugar de String. Funciona igual para la salida de cadena, es decir:

println("Pi is roughly \(3.1415926 ~> 3)")

imprime: Pi es aproximadamente 3.142
Por lo tanto, puede usarlo de la misma manera para las cadenas (incluso puede escribir: println (d ~> 2)), pero también puede usarlo para redondear valores directamente, es decir:

d = Double(slider.value) ~> 2

o lo que necesites ...

Stuepfnick
fuente
Obviamente, esto tiene la intención de ser un comentario, entiendo que necesita más espacio para hacer un punto, y es valioso, pero si va a escribirlo como una respuesta completa, hágalo útil por sí mismo, independientemente; podría agregar el código completo, por ejemplo, y luego un comentario y reconocimiento a Christian.
Jaime Gómez
@Jaime Gómez: No puedo comentar la respuesta anterior. Pero de todos modos, tuve alguna interpretación falsa * en él. No sé, si vale la pena conservarlo o si debería eliminarse. Por supuesto, esto puede usarse de manera similar solo para redondear (sin conversión de cadenas) y puede traducirse fácilmente a otros lenguajes de programación. * Supuse que con Double se redondea a aproximadamente 8 dígitos, lo que por supuesto fue un error, porque lo redondeé con Float y lo convertí en Double accidentalmente.
Stuepfnick
PD: Preferiría usar métodos similares más para redondear en general, no la salida de String, así que devuelva el tipo Double (¿y el método regular?) Nota : Si redondea un Float de esa manera (es decir, desde un Control deslizante) y el resultado a String it estará bien, como "0.1", pero si convierte ese Float a Double y luego a String * será: "0.100000001490116", ya que Float no es capaz de almacenar 0.1 exactamente, solo muy cerca. Supongo que es lo mismo con Double, solo con doble precisión ;) Así que siempre convierta a Double antes de redondear, por lo que será lo más exacto posible y también se convertirá a String.
Stuepfnick
PPS: Por supuesto, con Return Type Double, a veces es un poco diferente, es decir, si necesita establecer un texto de etiqueta, debe escribir: myLabel.text = "\ (d ~> 2)" en lugar de simplemente: myLabel. text = d ~> 2 , pero sigo pensando que la función es más práctica de esa manera. (por supuesto, todos pueden hacer lo que quieran, solo mis pensamientos ...)
Stuepfnick
-2

utilizar

CGFloat 

o

Float.roundTo(places:2)
Nicson
fuente
1
CGFloat no tiene miembros disponibles para
Chandni