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())
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
. 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
Où 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
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