Spécificateur de format de chaîne de précision dans Swift


395

Voici comment j'aurais précédemment tronqué un flotteur à deux décimales

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

J'ai vérifié les documents et le livre électronique, mais je n'ai pas pu le comprendre. Merci!

Réponses:


277

Ma meilleure solution jusqu'à présent, suite à la réponse 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

Je pense que c'est la solution la plus proche de Swift, liant les opérations de formatage directement au type de données. Il se pourrait bien qu'il y ait une bibliothèque intégrée d'opérations de formatage quelque part, ou peut-être qu'elle sera bientôt publiée. Gardez à l'esprit que la langue est toujours en version bêta.


76
C'est inutilement compliqué. la réponse de realityone fonctionne et est beaucoup plus concise.
Steven Marlowe

9
Bien sûr, si vous ne l'utilisez qu'une seule fois. Mais si vous vouliez avoir plus d'options de mise en forme en utilisant l'interpolation de chaînes (qui est beaucoup plus lisible), vous pouvez placer toutes les extensions de mise en forme dans un fichier ailleurs et y faire référence tout au long de votre projet. Bien sûr, Apple devrait idéalement fournir la bibliothèque de formatage.
Anton Tcholakov

2
Cette solution ne fonctionnera pas dans Swift 1.2 sans convertir le résultat en chaîne.
ibesora

Sympa, mais pas Swift 2 Friend.
LastMove

798

un moyen simple est:

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

print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))

9
println(String(format: "a float number: %.5f", 1.0321))
zaph

78
Je pense que c'est une meilleure réponse que la réponse acceptée. Il est beaucoup plus proche du style c standard printfsans avoir à écrire des extensions distinctes.
Keith Morris

9
N'oubliez pas la "Fondation d'importation" en haut du fichier.
Chris Gregg

3
C'est mieux que la réponse acceptée mais utilise toujours les méthodes Foundation (pontées vers Swift).

1
Soyez sûr deimport Foundation
NaN

125

J'ai trouvé que ça String.localizedStringWithFormatfonctionnait assez bien:

Exemple:

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

yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)

La question n'a rien à voir avec les unités de manutention. localizedStringWithFormat est bien, mais n'est pas lié.
AmitP

Je suis d'accord AmitP, il a été demandé avant que String (format: ..., arguments: ...) ne soit disponible
Valentin

84

C'est un moyen très rapide et simple qui n'a pas besoin de solution complexe.

let duration = String(format: "%.01f", 3.32323242)
// result = 3.3

Cela ne se compile pas (en utilisant 3.0.2 dans le sandbox Swift d'IBM):Col 16: 'init' has been renamed to 'init(describing:)'
Peter Dillinger

@PeterDillinger, vous passez une valeur facultative au lieu d'une valeur déballée.
Michael

63

La plupart des réponses ici sont valables. Toutefois, si vous formatez souvent le nombre, envisagez d'étendre la classe Float pour ajouter une méthode qui renvoie une chaîne formatée. Voir l'exemple de code ci-dessous. Celui-ci atteint le même objectif en utilisant un formateur et une extension de nombre.

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 console affiche:

The velocity is 12.33
The velocity is 12.3

Mise à jour 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)"
    }
}

12
Je souhaite que plus de gens utilisent NSNumberFormatter, comme cette réponse. Les autres réponses très votées ne reflètent tout simplement pas les paramètres régionaux du périphérique (par exemple, dans certains pays, ils utilisent une virgule pour une décimale; cela reflète cela; d'autres réponses ne le font pas).
Rob

3
La seule amélioration que j'aimerais voir, c'est le stockage du formateur pour un nombre donné - les NSNumberFormatters sont coûteux à construire.
Kendall Helmstetter Gelner

1
exactement ce que je cherchais! Merci
gunjot singh

Je sais que c'est une question un peu ancienne, mais elle NSNumberFormatterest assez lente à initialiser. Si possible, cela aide à en définir un et à le réutiliser. Cela dit, je lis ici cette question parce que ce n'est pas possible dans mon cas.
promacuser

44

Vous ne pouvez pas (encore) le faire avec une interpolation de chaîne. Votre meilleur pari sera toujours le formatage NSString:

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

En extrapolant à partir de python, il semble qu'une syntaxe raisonnable puisse être:

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

Ce qui vous permet ensuite de les utiliser comme:

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

Vous pouvez définir des opérateurs similaires pour tous les types numériques, malheureusement je n'ai pas trouvé de moyen de le faire avec des génériques.

Mise à jour Swift 5

À partir d'au moins Swift 5, Stringprend directement en charge l' format:initialiseur, il n'est donc pas nécessaire d'utiliser NSStringet l' @infixattribut n'est plus nécessaire, ce qui signifie que les exemples ci-dessus doivent être écrits comme suit:

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

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

Double.pi % "%5.3f"         // "3.142"

où avez-vous trouvé cette syntaxe `NSString (format:" formatString ", val) '. Je ne le vois pas dans le document iBooks d'Apple.
Duncan C

1
C'est la même chose que de construire n'importe quel objet objective-c à partir de swift. C'est la version rapide de[NSString stringWithFormat...
David Berry

Je t'ai eu. Je ne suis pas encore allé aussi loin dans le Swift iBook.
Duncan C

IIRC qui n'était pas dans le Swift iBook. C'était dans l'une des sessions de la WWDC. Interopérabilité Swift en profondeur
ahruss

2
Si vous implémentiez% comme en Python, cela devrait être l'inverse. "% 5.3f"% M_PI
Andy Dent

16

Pourquoi rendre cela si compliqué? Vous pouvez utiliser ceci à la place:

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

Voyez-le fonctionner dans Playground.

PS: Solution de: http://rrike.sh/xcode/rounding-various-decimal-places-swift/


C'est de loin la meilleure solution, je ne comprends pas comment ce n'est pas au sommet.
pjtnt11

7
chose nitpicky .. 1.500000000 ne serait que "1.5" et non "1.50"
styler1972

13
import Foundation

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

Usage

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

10

Une solution plus élégante et générique consiste à réécrire l' %opérateur 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]

Malheureusement, cela meurt en version bêta 6: erreur fatale: impossible de unsafeBitCast entre des types de tailles différentes.
binarymochi

@binarymochi Avec Beta 6: "Hello %@, This is pi : %.2f" % ["World", M_PI]ça marche, mais étrangement "%@ %@" % ["Hello", "World"]augmenter can't unsafeBitCast... Je suppose que cela sera corrigé dans la prochaine version.
Vincent Guerci

Pourriez-vous faire "," dans l'opérateur utilisé? '@infix func, (…', puis écrivez vos chaînes comme "Bonjour% @, c'est pi:% .2f", ["vous", M_PI])?
Rick

@Rick no you can't, ,n'est pas un opérateur de caractères valide, dans Swift et dans la plupart des langues. Et imo, il est préférable d'utiliser un %opérateur qui existe déjà dans d'autres langues. Voir developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Vincent Guerci

8

Swift 4

let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)

let temp: Float = div * 100 let string = String (format: "% .2f", locale: Locale.current, arguments: temp) cela me donne une erreur. Impossible de convertir la valeur de type "Float" en type d'argument attendu "[CVarArg]
Chandni

vous devez mettre ce 15.123 dans un tableau pour le faire fonctionner
Dorian Roy

3
pour moi fonctionne: let string = String (format: "% .2f", myString)
Grzegorz R. Kulesza

6

Vous pouvez toujours utiliser NSLog dans Swift comme dans Objective-C juste sans le signe @.

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

Edit: Après avoir travaillé avec Swift depuis un moment, je voudrais ajouter également cette variation

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

Production:

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

6

Détails

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

Solution 1

func arrondi () -> Double

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

func arrondi (règle _: 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"

fonction mutante ronde ()

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

mutation func round (règle _: 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

Solution 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)
    }
}

Usage

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

Échantillon complet

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)

Production

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

4
extension Double {
  func formatWithDecimalPlaces(decimalPlaces: Int) -> Double {
     let formattedString = NSString(format: "%.\(decimalPlaces)f", self) as String
     return Double(formattedString)!
     }
 }

 1.3333.formatWithDecimalPlaces(2)

3

Les réponses données jusqu'ici qui ont reçu le plus de votes reposent sur les méthodes NSString et vont exiger que vous ayez importé Foundation.

Cela dit, vous avez toujours accès à NSLog.

Je pense donc que la réponse à la question, si vous demandez comment continuer à utiliser NSLog dans Swift, est simplement:

import Foundation


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)

2

ici une solution rapide "pure"

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

2

Pouvoir d'extension

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

Sortie: La vitesse est de 12,3


2

manière moins de frappe:

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

1

Vous pouvez également créer un opérateur de cette manière

operator infix <- {}

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

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

1

Aussi avec arrondi:

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

1

utiliser la méthode ci-dessous

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

println(output)

1

Une version de l'opérateur ruby ​​/ python% de Vincent Guerci, mise à jour pour Swift 2.1:

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

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

1

Beaucoup de bonnes réponses ci-dessus, mais parfois un modèle est plus approprié que le genre de charabia "% .3f". Voici mon point de vue en utilisant un NumberFormatter dans 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

Ici, je voulais que 2 décimales soient toujours affichées, mais la troisième seulement si elle n'était pas nulle.


1

Mise à jour 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 ""
    }
}

1

Qu'en est-il des extensions sur les types Double et 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)"
      }
   }
}

Usage:

let aNumber: Double = 112465848348508.458758344
Swift.print("The number: \(aNumber.formatted(2))")

tirages: 112 465 848 348 508,46


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

0

Je ne connais pas deux décimales, mais voici comment imprimer des flottants avec zéro décimale, alors j'imagine que ça peut être 2, 3, ... (Remarque: vous devez convertir CGFloat en Double pour passer à String (format :) ou il verra une valeur de zéro)

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

0

Exemple Swift2: largeur d'écran d'un appareil iOS formatant le flottant en supprimant la décimale

print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))

-1

@Christian Dietrich:

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

cela pourrait aussi être:

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

[correction:] Désolé pour la confusion * - Bien sûr, cela fonctionne avec les doubles. Je pense que, plus pratique (si vous voulez que les chiffres soient arrondis, pas coupés), ce serait quelque chose comme ça:

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
}

Pour Float uniquement, remplacez simplement Double par Float, pow avec powf et round avec roundf.
Mise à jour: j'ai trouvé qu'il est plus pratique d'utiliser le type de retour Double au lieu de String. Il en va de même pour la sortie String, c'est-à-dire:

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

imprime: Pi est à peu près 3,142.
Vous pouvez donc l'utiliser de la même manière pour les chaînes (vous pouvez même toujours écrire: println (d ~> 2)), mais en plus, vous pouvez également l'utiliser pour arrondir directement les valeurs, à savoir:

d = Double(slider.value) ~> 2

ou tout ce dont vous avez besoin…


Ceci est évidemment destiné à être un commentaire, je comprends que vous avez besoin de plus d'espace pour faire un point, et c'est précieux, mais si vous voulez l'écrire comme une réponse à part entière, rendez-le utile en soi, indépendamment; vous pouvez ajouter le code complet, par exemple, puis une remarque et un accusé de réception à Christian.
Jaime Gómez

@Jaime Gómez: Je ne suis pas autorisé à commenter la réponse ci-dessus. Mais de toute façon, j'avais une fausse interprétation *. Je ne sais pas si cela vaut la peine d'être conservé ou s'il devrait être supprimé. Bien sûr, cela peut être utilisé d'une manière similaire juste pour l'arrondi (sans conversion de chaîne) et peut être facilement traduit dans d'autres langages de programmation. * J'ai supposé qu'avec Double, il est arrondi à environ 8 chiffres, ce qui bien sûr était une erreur, car je l'ai arrondi avec Float et l'ai converti en Double accidentellement.
Stuepfnick

PS: Je préférerais utiliser des méthodes similaires plus pour l'arrondi en général, pas la sortie String, donc retournez le type Double (& méthode régulière?) Sidenote : Si vous arrondissez un Float de cette façon (c'est-à-dire à partir d'un curseur) et le résultat à String it sera très bien, comme "0.1", mais si vous convertissez ce flotteur en double puis en chaîne *, ce sera: "0.100000001490116", car Float n'est pas capable de stocker exactement 0.1, seulement très proche. Je suppose que c'est la même chose avec Double, juste avec une double précision ;) Donc, convertissez toujours en Double avant d' arrondir, donc ce sera aussi exact que possible et convertira également en String fin.
Stuepfnick

PPS: Bien sûr, avec Return Type Double, c'est parfois un peu différent, c'est-à-dire que si vous devez définir un texte d'étiquette, vous devez écrire: myLabel.text = "\ (d ~> 2)" au lieu de simplement: myLabel. text = d ~> 2 , mais je pense toujours que la fonction est plus pratique de cette façon. (bien sûr tout le monde peut faire ce qu'il veut, juste mes pensées…)
Stuepfnick

-2

utilisation

CGFloat 

ou

Float.roundTo(places:2)

1
CGFloat n'a aucun tour de membre pour
Chandni
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.