Arrondir une valeur double à x nombre de décimales dans swift

395

Quelqu'un peut-il me dire comment arrondir une valeur double à x nombre de décimales dans Swift?

J'ai:

var totalWorkTimeInHours = (totalWorkTime/60/60)

Avec totalWorkTimeêtre un NSTimeInterval (double) en seconde.

totalWorkTimeInHours me donnera les heures, mais cela me donne la quantité de temps dans un nombre aussi long et précis, par exemple 1,543240952039 ......

Comment arrondir cela à, disons, 1,543 lorsque j'imprime totalWorkTimeInHours?

Leighton
la source
1
Voir ma réponse pour trouver jusqu'à 9 façons différentes pour arrondir un double en utilisant Darwin round(_:), Double round(), NSStringinitialiseur, Stringinitialiseur, NumberFormatter, double extension ou même NSDecimalNumberet Decimal.
Imanou Petit
@Rounded, un wrapper de propriété 5.1 rapide: gist.github.com/abhijithpp/1cc41b41a5d1c8f007da90f20bc0c65f
Abhijith

Réponses:

389

Vous pouvez utiliser la roundfonction de Swift pour accomplir cela.

Pour arrondir une Doubleprécision à 3 chiffres, multipliez-la d'abord par 1000, arrondissez-la et divisez le résultat arrondi par 1000:

let x = 1.23556789
let y = Double(round(1000*x)/1000)
print(y)  // 1.236

Hormis tout type de printf(...)ou String(format: ...)solutions, le résultat de cette opération est toujours de type Double.

EDIT:
En ce qui concerne les commentaires selon lesquels cela ne fonctionne parfois pas, veuillez lire ceci:

Ce que chaque programmeur devrait savoir sur l'arithmétique à virgule flottante

zisoft
la source
Pour certaines raisons, cela n'aide pas .. J'utilise ceci dans le cas suivant TransformOf <Double, String> (fromJSON: {Double (round (($ 0! As NSString) .doubleValue * 100) / 100)}, toJSON: {"(0 $)"})
Fawkes
29
Ne fonctionne pas pour moi dans la cour de récréation: let rate = 9.94999999999; Double(round(rate * 100) / 100);Sortie: 9.94999999999, 9.949999999999999ne fonctionne que pour l'impression, mais comment puis-je l'assigner à une variable?
Alexander Yakovlev
Vous devez utiliser Decimal pour cela, pas des doubles simples.
csotiriou
13
"Ce que tout informaticien devrait savoir sur l'arithmétique à virgule flottante" contient 73 pages. Quel est le TL; DR là-dessus? :)
JaredH
1
@HardikDG Je ne me souviens pas, désolé :-)
Alexander Yakovlev
431

Extension pour Swift 2

Une solution plus générale est l'extension suivante, qui fonctionne avec Swift 2 et iOS 9:

extension Double {
    /// Rounds the double to decimal places value
    func roundToPlaces(places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return round(self * divisor) / divisor
    }
}


Extension pour Swift 3

Dans Swift 3 roundest remplacé par rounded:

extension Double {
    /// Rounds the double to decimal places value
    func rounded(toPlaces places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}


Exemple qui renvoie Double arrondi à 4 décimales:

let x = Double(0.123456789).roundToPlaces(4)  // x becomes 0.1235 under Swift 2
let x = Double(0.123456789).rounded(toPlaces: 4)  // Swift 3 version
Sébastien
la source
17
La nature de Swift's Double semble être imprécise - en raison de la façon dont il est stocké / accédé en binaire, même en utilisant cette fonction d'arrondi ne renverra pas un nombre arrondi à 3 décimales: par exemple, round(8.46 * pow(10.0, 3.0)) / pow(10.0, 3.0)renvoie 8.460000000000001. Faire de même avec Float, du moins dans ce scénario , semble en fait fonctionner: les round(Float(8.46) * pow(10.0, 3.0)) / pow(10.0, 3.0)rendements 8.46. Juste quelque chose à noter.
Ben Saufley
2
Malheureusement, cela ne fonctionne plus dans Swift 3, je reçois cette erreurNo '*' candidates produce the expected contextual result type 'FloatingPointRoundingRule'
koen
2
J'ai mis à jour la solution et ajouté une extension pour Swift 3.
Sebastian
2
Pour être plus rapide 3 ... vous devriez changer pour func arrondi (toPlaces places: Int) -> Double
FouZ
2
@BenSaufley Mais cela ne fonctionne pas non plus si vous entrez 98,68. Dans ce cas, je reçois 98.6800003
Alexander Khitev
340

Comment arrondir ce chiffre à, disons, 1,543 lorsque j'imprime totalWorkTimeInHours?

Pour arrondir totalWorkTimeInHoursà 3 chiffres pour l'impression, utilisez le Stringconstructeur qui prend une formatchaîne:

print(String(format: "%.3f", totalWorkTimeInHours))
vacawama
la source
24
C'est la troncature, pas l'arrondi
Eyeball
33
@Eyeball: En fait, il fait le tour. Il s'agit du même comportement que la fonctionnalité C printf, qui arrondit aux chiffres demandés. Alors String(format: "%.3f", 1.23489)imprime1.235
zisoft
6
L'affiche originale recherche une valeur numérique à utiliser, pas une chaîne à afficher.
pr1001
17
@ pr1001, peut-être, mais ce n'était pas clair à l'époque et 46 autres personnes ont trouvé ma réponse utile. Stack Overflow est plus qu'une simple aide à l'OP.
vacawama
3
étrange, cela renvoie 0,00 à chaque fois.
Eric H
254

Avec Swift 5, selon vos besoins, vous pouvez choisir l'un des 9 styles suivants afin d'avoir un résultat arrondi de a Double.


#1. Utilisation de la FloatingPoint rounded()méthode

Dans le cas le plus simple, vous pouvez utiliser la Double rounded()méthode.

let roundedValue1 = (0.6844 * 1000).rounded() / 1000
let roundedValue2 = (0.6849 * 1000).rounded() / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 2. Utilisation de la FloatingPoint rounded(_:)méthode

let roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000
let roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 3. Utilisation de la roundfonction Darwin

La Fondation propose une roundfonction via Darwin.

import Foundation

let roundedValue1 = round(0.6844 * 1000) / 1000
let roundedValue2 = round(0.6849 * 1000) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 4. Utilisation d'une Doubleméthode personnalisée d'extension construite avec Darwin roundet des powfonctions

Si vous souhaitez répéter l'opération précédente plusieurs fois, la refactorisation de votre code peut être une bonne idée.

import Foundation

extension Double {
    func roundToDecimal(_ fractionDigits: Int) -> Double {
        let multiplier = pow(10, Double(fractionDigits))
        return Darwin.round(self * multiplier) / multiplier
    }
}

let roundedValue1 = 0.6844.roundToDecimal(3)
let roundedValue2 = 0.6849.roundToDecimal(3)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 5. Utilisation de la NSDecimalNumber rounding(accordingToBehavior:)méthode

Si nécessaire, NSDecimalNumberoffre une solution détaillée mais puissante pour arrondir les nombres décimaux.

import Foundation

let scale: Int16 = 3

let behavior = NSDecimalNumberHandler(roundingMode: .plain, scale: scale, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true)

let roundedValue1 = NSDecimalNumber(value: 0.6844).rounding(accordingToBehavior: behavior)
let roundedValue2 = NSDecimalNumber(value: 0.6849).rounding(accordingToBehavior: behavior)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 6. Utilisation de la NSDecimalRound(_:_:_:_:)fonction

import Foundation

let scale = 3

var value1 = Decimal(0.6844)
var value2 = Decimal(0.6849)

var roundedValue1 = Decimal()
var roundedValue2 = Decimal()

NSDecimalRound(&roundedValue1, &value1, scale, NSDecimalNumber.RoundingMode.plain)
NSDecimalRound(&roundedValue2, &value2, scale, NSDecimalNumber.RoundingMode.plain)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

#7. Utilisation de l' NSString init(format:arguments:)initialiseur

Si vous souhaitez renvoyer un NSStringde votre opération d'arrondi, l'utilisation de l' NSStringinitialiseur est une solution simple mais efficace.

import Foundation

let roundedValue1 = NSString(format: "%.3f", 0.6844)
let roundedValue2 = NSString(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

# 8. Utilisation de l' String init(format:_:)initialiseur

Le Stringtype de Swift est ponté avec la NSStringclasse de la Fondation . Par conséquent, vous pouvez utiliser le code suivant afin de renvoyer un Stringde votre opération d'arrondi:

import Foundation

let roundedValue1 = String(format: "%.3f", 0.6844)
let roundedValue2 = String(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

# 9. En utilisantNumberFormatter

Si vous prévoyez d'obtenir un résultat String?de votre opération d'arrondi, NumberFormatterpropose une solution hautement personnalisable.

import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.roundingMode = NumberFormatter.RoundingMode.halfUp
formatter.maximumFractionDigits = 3

let roundedValue1 = formatter.string(from: 0.6844)
let roundedValue2 = formatter.string(from: 0.6849)
print(String(describing: roundedValue1)) // prints Optional("0.684")
print(String(describing: roundedValue2)) // prints Optional("0.685")
Imanou Petit
la source
1
Très bonne réponse. Je pourrais suggérer sur # 5 que vous pourriez envisager d'utiliser Decimal, qui est un pont gratuit NSDecimalNumber. Decimalest de type natif de Swift et offre un soutien plus élégant pour les opérateurs autochtones comme +, -, etc.
Rob
@Rob J'ai mis à jour ma réponse avec la NSDecimalRound(_:_:_:_:)fonction. Merci.
Imanou Petit
L'utilisation du choix # 9 garantira que vous vous attendez à la fraction fixe (nombre de chiffres de précision), disons le nombre décimal 43.12345 et la fraction = 6, vous obtenez 43.123450
Almas Adilbek
1
@ImanouPetit Merci d'avoir posté ceci. Je peux supprimer quelques extensions.
Adrian
Je suis triste, NumberFormatterc'est la dernière option alors qu'elle devrait être la première pour présenter des chiffres aux utilisateurs. Aucune autre méthode ne génère de nombres correctement localisés.
Sulthan
93

Dans Swift 2.0 et Xcode 7.2:

let pi: Double = 3.14159265358979
String(format:"%.2f", pi)

Exemple:

entrez la description de l'image ici

Claudio Guirunas
la source
50

Ceci est un code entièrement travaillé

Swift 3.0 / 4.0 / 5.0, Xcode 9.0 GM / 9.2 et supérieur

let doubleValue : Double = 123.32565254455
self.lblValue.text = String(format:"%.f", doubleValue)
print(self.lblValue.text)

sortie - 123

let doubleValue : Double = 123.32565254455
self.lblValue_1.text = String(format:"%.1f", doubleValue)
print(self.lblValue_1.text)

sortie - 123,3

let doubleValue : Double = 123.32565254455
self.lblValue_2.text = String(format:"%.2f", doubleValue)
print(self.lblValue_2.text)

sortie - 123,33

let doubleValue : Double = 123.32565254455
self.lblValue_3.text = String(format:"%.3f", doubleValue)
print(self.lblValue_3.text)

sortie - 123.326

Krunal Patel
la source
1
une ligne?, ressemble à 3 lignes;)
Petter Friberg
vous ne pouvez pas calculer les choses en utilisant des chaînes, je ne pense pas que ce soit une bonne réponse car c'est uniquement pour l'affichage.
JBarros35
25

S'appuyant sur la réponse de Yogi, voici une fonction Swift qui fait le travail:

func roundToPlaces(value:Double, places:Int) -> Double {
    let divisor = pow(10.0, Double(places))
    return round(value * divisor) / divisor
}
Cendre
la source
20

Dans Swift 3.0 et Xcode 8.0:

extension Double {
    func roundTo(places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

Utilisez cette extension comme ceci:

let doubleValue = 3.567
let roundedValue = doubleValue.roundTo(places: 2)
print(roundedValue) // prints 3.56
jaiswal Rajan
la source
19

Swift 4, Xcode 10

yourLabel.text =  String(format:"%.2f", yourDecimalValue)
Naishta
la source
1
Je n'ai pas downvote, mais je pense que la raison pourrait être parce que cela renvoie une représentation sous forme de chaîne d'un nombre, pas le nombre. Ce qui est bien si c'est tout ce dont vous avez besoin, mais vous voudrez peut-être que le nombre lui-même soit arrondi pour une utilisation ultérieure. L'OP a dit "quand j'imprime", donc je pense que c'est une solution acceptable, facile et propre dans ce cas.
Ben Stahl
1
Parfait. Solution en une ligne. J'avais juste besoin d'afficher les valeurs décimales sous forme de chaînes dans mes étiquettes.
zeeshan
18

Le code pour les chiffres spécifiques après les décimales est:

var a = 1.543240952039
var roundedString = String(format: "%.3f", a)

Ici, le% .3f indique au swift de faire ce nombre arrondi à 3 décimales. Et si vous voulez un double nombre, vous pouvez utiliser ce code:

// Chaîne en double

var roundedString = Double(String(format: "%.3f", b))

Ramazan Karami
la source
14

Utilisez la bibliothèque Foundation Darwin intégrée

SWIFT 3

extension Double {
    func round(to places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return Darwin.round(self * divisor) / divisor
    }
}

Usage:

let number:Double = 12.987654321
print(number.round(to: 3)) 

Sorties: 12,988

George Filippakos
la source
9

Un moyen pratique peut être l'utilisation de l' extension de type Double

extension Double {
    var roundTo2f: Double {return Double(round(100 *self)/100)  }
    var roundTo3f: Double {return Double(round(1000*self)/1000) }
}

Usage:

let regularPie:  Double = 3.14159
var smallerPie:  Double = regularPie.roundTo3f  // results 3.142
var smallestPie: Double = regularPie.roundTo2f  // results 3.14
Marco Leong
la source
9

Si vous souhaitez arrondir des Doublevaleurs, vous pouvez utiliser Swift Decimalafin de ne pas introduire d'erreurs pouvant apparaître lorsque vous essayez de calculer avec ces valeurs arrondies. Si vous utilisez Decimal, il peut représenter avec précision les valeurs décimales de cette valeur arrondie à virgule flottante.

Vous pouvez donc faire:

extension Double {
    /// Convert `Double` to `Decimal`, rounding it to `scale` decimal places.
    ///
    /// - Parameters:
    ///   - scale: How many decimal places to round to. Defaults to `0`.
    ///   - mode:  The preferred rounding mode. Defaults to `.plain`.
    /// - Returns: The rounded `Decimal` value.

    func roundedDecimal(to scale: Int = 0, mode: NSDecimalNumber.RoundingMode = .plain) -> Decimal {
        var decimalValue = Decimal(self)
        var result = Decimal()
        NSDecimalRound(&result, &decimalValue, scale, mode)
        return result
    }
}

Ensuite, vous pouvez obtenir la Decimalvaleur arrondie comme suit:

let foo = 427.3000000002
let value = foo.roundedDecimal(to: 2) // results in 427.30

Et si vous souhaitez l'afficher avec un nombre spécifié de décimales (ainsi que localiser la chaîne pour les paramètres régionaux actuels de l'utilisateur), vous pouvez utiliser un NumberFormatter:

let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

if let string = formatter.string(for: value) {
    print(string)
}
Rob
la source
2
La meilleure réponse jusqu'à présent.
Codetard
(4.81).roundedDecimal(to: 2, mode: .down)renverra 4,8 au lieu de 4,81, utilisez Decimal(string: self.description)!pour une précisiondecimalValue
vk.edward.li
1
@ vk.edward.li - Oui, il faut se méfier d'arrondir les décimales vers le haut / bas, car les valeurs comme 4.81 ne peuvent tout simplement pas être représentées avec précision avec Double(cela devient 4.8099999999999996). Mais je déconseille l'utilisation description(car l'arrondi qu'il utilise n'est pas documenté et est susceptible de changer). Si vous voulez vraiment faire des mathématiques avec une précision décimale, vous devez éviter Doublecomplètement et utiliser à la place Decimaldirectement (par exemple Decimal(sign: .plus, exponent: -2, significand: 481)ou Decimal(string: "4.81"). Mais ne pas utiliser description.
Rob
@Rob généralement, il est impossible d'obtenir la valeur de chaîne de "4,81" si elle est stockée en tant que Double, vous devez donc utiliser self.description (un algorithme Grisu2 modifié) pour corriger la précision qui est déjà perdue
vk.edward.li
Je comprends votre point. Je suis juste en désaccord avec votre solution. Le comportement d'arrondi de la descriptionméthode n'est ni documenté ni garanti. De plus, ce n'est pas localisé. À mon humble avis, c'est une erreur à utiliser descriptionà des fins autres que la journalisation. J'utiliserais Decimaltout au long, en évitant d'utiliser Doublecomplètement, ou j'utiliserais simplement un mode d'arrondi différent. Ou, si vous le devez, utilisez votre propre méthode localisée qui utilise l'algorithme de style Grisu (mais cela semble inutile lorsque vous savez combien de décimales vous voulez arrondir). Mais j'éviterais de compter sur ce comportement accessoire de description.
Rob
8

Il s'agit d'une sorte de longue solution de contournement, qui peut être utile si vos besoins sont un peu plus complexes. Vous pouvez utiliser un formateur de nombres dans Swift.

let numberFormatter: NSNumberFormatter = {
    let nf = NSNumberFormatter()
    nf.numberStyle = .DecimalStyle
    nf.minimumFractionDigits = 0
    nf.maximumFractionDigits = 1
    return nf
}()

Supposons que votre variable que vous souhaitez imprimer soit

var printVar = 3.567

Cela garantira qu'il est retourné dans le format souhaité:

numberFormatter.StringFromNumber(printVar)

Le résultat sera donc ici "3,6" (arrondi). Bien que ce ne soit pas la solution la plus économique, je la donne parce que l'OP a mentionné l'impression (auquel cas une chaîne n'est pas indésirable), et parce que cette classe permet de définir plusieurs paramètres.

Inkidu616
la source
1
Une note rapide que tout formateur est plutôt coûteux par programme, ce qui le rend peu judicieux pour les tâches qui doivent être effectuées rapidement ou de manière répétitive.
Jonathan Thornton
7

j'utiliserais

print(String(format: "%.3f", totalWorkTimeInHours))

et changez .3f en n'importe quel nombre de nombres décimaux dont vous avez besoin

Mohsen Hossein pour
la source
Il voulait imprimer avec 3 chiffres, ne pas l'obtenir dans NSTimeInterval
Mohsen Hossein pour
7

Soit:

  1. En utilisant String(format:):

    • Typecast Doublevers Stringavec %.3fspécificateur de format, puis retour àDouble

      Double(String(format: "%.3f", 10.123546789))!
    • Ou étendez-vous Doublepour gérer les décimales N:

      extension Double {
          func rounded(toDecimalPlaces n: Int) -> Double {
              return Double(String(format: "%.\(n)f", self))!
          }
      }
  2. Par calcul

    • multipliez par 10 ^ 3, arrondissez-le puis divisez par 10 ^ 3 ...

      (1000 * 10.123546789).rounded()/1000
    • Ou étendez-vous Doublepour gérer les décimales N:

      extension Double {    
          func rounded(toDecimalPlaces n: Int) -> Double {
              let multiplier = pow(10, Double(n))
              return (multiplier * self).rounded()/multiplier
          }
      }
staticVoidMan
la source
6

Il s'agit d'un algorithme plus flexible d'arrondi à N chiffres significatifs

Solution Swift 3

extension Double {
// Rounds the double to 'places' significant digits
  func roundTo(places:Int) -> Double {
    guard self != 0.0 else {
        return 0
    }
    let divisor = pow(10.0, Double(places) - ceil(log10(fabs(self))))
    return (self * divisor).rounded() / divisor
  }
}


// Double(0.123456789).roundTo(places: 2) = 0.12
// Double(1.23456789).roundTo(places: 2) = 1.2
// Double(1234.56789).roundTo(places: 2) = 1200
Nikita Ivaniushchenko
la source
6

La meilleure façon de formater une double propriété est d'utiliser les méthodes prédéfinies d'Apple.

mutating func round(_ rule: FloatingPointRoundingRule)

FloatingPointRoundingRule est une énumération qui a les possibilités suivantes

Cas de dénombrement:

case awayFromZero Arrondit à la valeur autorisée la plus proche dont la magnitude est supérieure ou égale à celle de la source.

case down Arrondit à la valeur autorisée la plus proche inférieure ou égale à la source.

case toNearestOrAwayFromZero Arrondit à la valeur autorisée la plus proche; si deux valeurs sont également proches, celle de plus grande ampleur est choisie.

case toNearestOrEven Arrondit à la valeur autorisée la plus proche; si deux valeurs sont également proches, la paire est choisie.

case vers zéro arrondi à la valeur autorisée la plus proche dont la magnitude est inférieure ou égale à celle de la source.

case up Arrondit à la valeur autorisée la plus proche, supérieure ou égale à la source.

var aNumber : Double = 5.2
aNumber.rounded(.up) // 6.0
Abuzar Manzoor
la source
6

arrondir une valeur double à x nombre décimal
NO . de chiffres après la décimale

var x = 1.5657676754
var y = (x*10000).rounded()/10000
print(y)  // 1.5658 

var x = 1.5657676754 
var y = (x*100).rounded()/100
print(y)  // 1.57 

var x = 1.5657676754
var y = (x*10).rounded()/10
print(y)  // 1.6
Ayman Badr
la source
Que se passe-t-il avec ce code? Que démontrent les trois exemples?
rene
Les réponses codées uniquement ne sont pas utiles, veuillez essayer d'expliquer ce que fait chacun de ces exemples.
Moe
5

Pas Swift mais je suis sûr que vous avez l'idée.

pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;
yogi
la source
4

Cela semble fonctionner dans Swift 5.

Assez surpris qu'il n'y ait pas déjà de fonction standard pour cela.

// Troncature des doubles à n décimales avec arrondi

extension Double {

    func truncate(to places: Int) -> Double {
    return Double(Int((pow(10, Double(places)) * self).rounded())) / pow(10, Double(places))
    }

}
Matiu Awaiti
la source
2

Vous pouvez ajouter cette extension:

extension Double {
    var clean: String {
        return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)
    }
}

et appelez-le comme ceci:

let ex: Double = 10.123546789
print(ex.clean) // 10.12
TOUZENE Mohamed Wassim
la source
Celui-ci est une implémentation soignée de le représenter comme une chaîne. Je me demande s'il est possible ou rationnel d'écrire une extension du nombre de représentation des chiffres après la période en la maintenant toujours en Double.
thinkswift
2

Pour éviter les imperfections du flotteur, utilisez Decimal

extension Float {
    func rounded(rule: NSDecimalNumber.RoundingMode, scale: Int) -> Float {
        var result: Decimal = 0
        var decimalSelf = NSNumber(value: self).decimalValue
        NSDecimalRound(&result, &decimalSelf, scale, rule)
        return (result as NSNumber).floatValue
    }
}

ex.
1075,58 arrondis à 1075,57 lorsque vous utilisez Float avec échelle: 2 et .down
1075,58 arrondis à 1075,58 lorsque vous utilisez Decimal avec échelle: 2 et .down

Yervand Saribekyan
la source
1

J'ai trouvé cela me demandant s'il était possible de corriger l'entrée d'un utilisateur. C'est-à-dire s'ils entrent trois décimales au lieu de deux pour un montant en dollars. Dites 1.111 au lieu de 1.11 pouvez-vous le corriger en arrondissant? La réponse pour de nombreuses raisons est non! Avec de l'argent, plus de 0,001 finirait par causer des problèmes dans un vrai chéquier.

Voici une fonction pour vérifier l'entrée des utilisateurs pour trop de valeurs après la période. Mais ce qui permettra 1., 1.1 et 1.11.

Il est supposé que la valeur a déjà été vérifiée pour la conversion réussie d'une chaîne en un double.

//func need to be where transactionAmount.text is in scope

func checkDoublesForOnlyTwoDecimalsOrLess()->Bool{


    var theTransactionCharacterMinusThree: Character = "A"
    var theTransactionCharacterMinusTwo: Character = "A"
    var theTransactionCharacterMinusOne: Character = "A"

    var result = false

    var periodCharacter:Character = "."


    var myCopyString = transactionAmount.text!

    if myCopyString.containsString(".") {

         if( myCopyString.characters.count >= 3){
                        theTransactionCharacterMinusThree = myCopyString[myCopyString.endIndex.advancedBy(-3)]
         }

        if( myCopyString.characters.count >= 2){
            theTransactionCharacterMinusTwo = myCopyString[myCopyString.endIndex.advancedBy(-2)]
        }

        if( myCopyString.characters.count > 1){
            theTransactionCharacterMinusOne = myCopyString[myCopyString.endIndex.advancedBy(-1)]
        }


          if  theTransactionCharacterMinusThree  == periodCharacter {

                            result = true
          }


        if theTransactionCharacterMinusTwo == periodCharacter {

            result = true
        }



        if theTransactionCharacterMinusOne == periodCharacter {

            result = true
        }

    }else {

        //if there is no period and it is a valid double it is good          
        result = true

    }

    return result


}
Homme de montagne
la source
1
//find the distance between two points
let coordinateSource = CLLocation(latitude: 30.7717625, longitude:76.5741449 )
let coordinateDestination = CLLocation(latitude: 29.9810859, longitude: 76.5663599)
let distanceInMeters = coordinateSource.distance(from: coordinateDestination)
let valueInKms = distanceInMeters/1000
let preciseValueUptoThreeDigit = Double(round(1000*valueInKms)/1000)
self.lblTotalDistance.text = "Distance is : \(preciseValueUptoThreeDigit) kms"
Davender Verma
la source
1
extension String{
  var roundedValue:String {
     return String(format: "%.3f", self)
}}

Utilisation:

totalWorkTimeInHours.roundedValue
Bhargav Sejpal
la source
1

En voici un pour SwiftUI si vous avez besoin d'un élément Text avec la valeur numérique.

struct RoundedDigitText : View {
    let digits : Int
    let number : Double

    var body : some View {
        Text(String(format: "%.\(digits)f", number))
    }
}
FrankByte.com
la source