Comment arrondir un double à l’Int le plus proche en swift?

J’essaie de faire un calculateur de taux de croissance ( Double ) qui arrondira le résultat au nombre entier le plus proche et recalculera à partir de là, en tant que tel:

 let firstUsers = 10.0 let growth = 0.1 var users = firstUsers var week = 0 while users < 14 { println("week \(week) has \(users) users") users += users * growth week += 1 } 

mais j’ai été incapable jusqu’ici.

EDIT je l’ai fait un peu comme ça:

 var firstUsers = 10.0 let growth = 0.1 var users:Int = Int(firstUsers) var week = 0 while users <= 14 { println("week \(week) has \(users) users") firstUsers += firstUsers * growth users = Int(firstUsers) week += 1 } 

Bien que cela ne me dérange pas que cela arrondisse toujours, je ne l’aime pas parce que firstUsers devait devenir une variable et changer tout au long du programme (pour effectuer le calcul suivant), ce que je ne veux pas que cela se produise .

Il y a un round disponible dans la bibliothèque de la Foundation (c’est en fait dans Darwin , mais Foundation importe Darwin et la plupart du temps, vous voudrez utiliser Foundation au lieu d’utiliser directement Darwin ) .

 import Foundation users = round(users) 

Exécuter votre code dans une aire de jeux et appeler ensuite:

 print(round(users)) 

Les sorties:

15.0

round() arrondit toujours lorsque la décimale est >= .5 et moins quand elle est < .5 (arrondissement standard). Vous pouvez utiliser floor() pour forcer l'arrondi et ceil() pour forcer l'arrondi.

Si vous devez arrondir à un endroit spécifique, vous devez multiplier par pow(10.0, number of places) , puis round , puis diviser par pow(10, number of places) :

Arrondir à 2 décimales:

 let numberOfPlaces = 2.0 let multiplier = pow(10.0, numberOfPlaces) let num = 10.12345 let rounded = round(10.12345 * multiplier) / multiplier print(rounded) 

Les sorties:

10.12

Note: En raison de la façon dont fonctionne le calcul en virgule flottante, l' rounded peut ne pas toujours être parfaitement précis. Il est préférable d'y penser plus d'une approximation de l'arrondissement. Si vous le faites à des fins d'affichage, il est préférable d'utiliser le formatage de chaîne pour formater le nombre plutôt que d'utiliser les mathématiques pour le arrondir.

Pour arrondir un double au nombre entier le plus proche, utilisez simplement round() .

 var x = 3.7 x.round() // x = 4.0 

Si vous ne voulez pas modifier la valeur d’origine, utilisez rounded() :

 let x = 3.7 let y = x.rounded() // y = 4.0. x = 3.7 

Comme on peut s’y attendre ( ou peut-être pas ), un nombre comme 3.5 est arrondi et un nombre comme -3.5 est arrondi. Si vous avez besoin d’un comportement d’arrondissement différent, vous pouvez utiliser l’une des règles d’arrondi . Par exemple:

 var x = 3.7 x.round(.towardZero) // 3.0 

Si vous avez besoin d’un Int réel, alors il suffit de le convertir en un seul:

 let myInt = Int(myDouble.rounded()) 

Remarques

  • Cette réponse est complètement réécrite. Mon ancienne réponse portait sur les fonctions mathématiques du C comme la round , le lround , le floor et le ceil . Cependant, maintenant que Swift a cette fonctionnalité intégrée, je ne peux plus recommander d’utiliser ces fonctions. Merci à @dfri pour me l’avoir signalé. Découvrez l’excellente réponse de @dfri ici . J’ai aussi fait quelque chose de similaire pour arrondir un CGFloat .

Swift 3 & 4 – utilisation de la méthode rounded(_:) comme blueprinted dans le protocole FloatingPoint

Le protocole FloatingPoint (auquel se conforme par exemple Double et Float ) imprime la méthode rounded(_:)

 func rounded(_ rule: FloatingPointRoundingRule) -> Self 

FloatingPointRoundingRule est une énumération énumérant un certain nombre de règles d’arrondi différentes:

case awayFromZero

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

case down

Arrondissez à la valeur autorisée la plus proche inférieure ou égale à la source.

case toNearestOrAwayFromZero

Arrondir à la valeur autorisée la plus proche; si deux valeurs sont également proches, celle de plus grande magnitude est choisie.

case toNearestOrEven

Arrondir à la valeur autorisée la plus proche; si deux valeurs sont également proches, la même est choisie.

case towardZero

Arrondissez à la valeur autorisée la plus proche dont la magnitude est inférieure ou égale à celle de la source.

case up

Arrondissez à la valeur autorisée la plus proche supérieure ou égale à la source.

Nous utilisons des exemples similaires à ceux de l’excellente réponse de @ Suragch pour montrer ces différentes options d’arrondi dans la pratique.

.awayFromZero

Arrondir à la valeur autorisée la plus proche dont la magnitude est supérieure ou égale à celle de la source; pas d’équivalent direct parmi les fonctions C, car cela utilise, sous condition de signe de self , de ceil ou de floor , respectivement, des valeurs de self positives et négatives.

 3.000.rounded(.awayFromZero) // 3.0 3.001.rounded(.awayFromZero) // 4.0 3.999.rounded(.awayFromZero) // 4.0 (-3.000).rounded(.awayFromZero) // -3.0 (-3.001).rounded(.awayFromZero) // -4.0 (-3.999).rounded(.awayFromZero) // -4.0 

.down

Équivalent à la fonction C floor .

 3.000.rounded(.down) // 3.0 3.001.rounded(.down) // 3.0 3.999.rounded(.down) // 3.0 (-3.000).rounded(.down) // -3.0 (-3.001).rounded(.down) // -4.0 (-3.999).rounded(.down) // -4.0 

.toNearestOrAwayFromZero

Equivalent à la fonction C round .

 3.000.rounded(.toNearestOrAwayFromZero) // 3.0 3.001.rounded(.toNearestOrAwayFromZero) // 3.0 3.499.rounded(.toNearestOrAwayFromZero) // 3.0 3.500.rounded(.toNearestOrAwayFromZero) // 4.0 3.999.rounded(.toNearestOrAwayFromZero) // 4.0 (-3.000).rounded(.toNearestOrAwayFromZero) // -3.0 (-3.001).rounded(.toNearestOrAwayFromZero) // -3.0 (-3.499).rounded(.toNearestOrAwayFromZero) // -3.0 (-3.500).rounded(.toNearestOrAwayFromZero) // -4.0 (-3.999).rounded(.toNearestOrAwayFromZero) // -4.0 

Vous pouvez également accéder à cette règle d’arrondi en utilisant la méthode d’argument nul rounded() .

 3.000.rounded() // 3.0 // ... (-3.000).rounded() // -3.0 // ... 

.toNearestOrEven

Arrondir à la valeur autorisée la plus proche; si deux valeurs sont également proches, la même est choisie; équivalent à la fonction C rint (/ very similar to nearbyint ).

 3.499.rounded(.toNearestOrEven) // 3.0 3.500.rounded(.toNearestOrEven) // 4.0 (up to even) 3.501.rounded(.toNearestOrEven) // 4.0 4.499.rounded(.toNearestOrEven) // 4.0 4.500.rounded(.toNearestOrEven) // 4.0 (down to even) 4.501.rounded(.toNearestOrEven) // 4.0 

.towardZero

Equivalent à la fonction C trunc .

 3.000.rounded(.towardZero) // 3.0 3.001.rounded(.towardZero) // 3.0 3.999.rounded(.towardZero) // 3.0 (-3.000).rounded(.towardZero) // 3.0 (-3.001).rounded(.towardZero) // 3.0 (-3.999).rounded(.towardZero) // 3.0 

Si l’object de l’arrondi est de se préparer à travailler avec un entier (par exemple, en utilisant l’initialisation d’ Int par FloatPoint après l’arrondi), nous pourrions simplement utiliser le fait que lors de l’initialisation d’un Int utilisant un Double (ou Float etc.) sera tronqué.

 Int(3.000) // 3 Int(3.001) // 3 Int(3.999) // 3 Int(-3.000) // -3 Int(-3.001) // -3 Int(-3.999) // -3 

.up

Equivalent à la fonction C ceil .

 3.000.rounded(.up) // 3.0 3.001.rounded(.up) // 4.0 3.999.rounded(.up) // 4.0 (-3.000).rounded(.up) // 3.0 (-3.001).rounded(.up) // 3.0 (-3.999).rounded(.up) // 3.0 

Addendum: visite du code source de FloatingPoint pour vérifier l’équivalence des fonctions C avec les différentes règles FloatingPointRoundingRule

Si nous le souhaitons, nous pouvons examiner le code source du protocole FloatingPoint pour voir directement les équivalents de la fonction C des règles FloatingPointRoundingRule publiques.

À partir de swift / stdlib / public / core / FloatingPoint.swift.gyb, nous voyons que l’implémentation par défaut de la méthode rounded(_:) fait de nous une méthode round(_:) :

 public func rounded(_ rule: FloatingPointRoundingRule) -> Self { var lhs = self lhs.round(rule) return lhs } 

De swift / stdlib / public / core / FloatingPointTypes.swift.gyb, nous trouvons l’implémentation par défaut de round(_:) , dans laquelle l’équivalence entre les règles FloatingPointRoundingRule et les fonctions d’arrondi C est apparente:

 public mutating func round(_ rule: FloatingPointRoundingRule) { switch rule { case .toNearestOrAwayFromZero: _value = Builtin.int_round_FPIEEE${bits}(_value) case .toNearestOrEven: _value = Builtin.int_rint_FPIEEE${bits}(_value) case .towardZero: _value = Builtin.int_trunc_FPIEEE${bits}(_value) case .awayFromZero: if sign == .minus { _value = Builtin.int_floor_FPIEEE${bits}(_value) } else { _value = Builtin.int_ceil_FPIEEE${bits}(_value) } case .up: _value = Builtin.int_ceil_FPIEEE${bits}(_value) case .down: _value = Builtin.int_floor_FPIEEE${bits}(_value) } } 

Swift 3: Si vous voulez arrondir à un certain nombre de chiffres, par exemple 5.678434 -> 5.68, vous pouvez simplement combiner la fonction round () ou roundf () avec une multiplication:

  let value:Float = 5.678434 let roundedValue = roundf(value * 100) / 100 print(roundedValue) //5.68 

Swift 3

var myNum = 8.09

myNum.rounded () // résultat = 8 qui est stocké dans myNum

Vous pouvez également étendre FloatingPoint dans Swift 3 comme suit:

 extension FloatingPoint { func rounded(to n: Int) -> Self { return (self / Self(n)).rounded() * Self(n) } } 324.0.rounded(to: 5) // 325