Swift 3 & 4 - utiliser la rounded(_:)
méthode telle que définie dans le FloatingPoint
protocole
Le FloatingPoint
protocole (auquel par exemple Double
et se Float
conforme) définit la rounded(_:)
méthode
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 amplitude est choisie.
case toNearestOrEven
Arrondir à la valeur autorisée la plus proche; si deux valeurs sont également proches, la paire 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 qui est 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, conditionnellement au signe de self
, ceil
ou floor
, pour des valeurs positives et négatives de self
, respectivement.
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 floor
fonction C.
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
Équivalent à la round
fonction C.
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
Cette règle d'arrondi est également accessible en utilisant la rounded()
méthode d' argument zéro .
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 paire est choisie; équivalent à la fonction C rint
(/ très similaire à 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) // 5.0 (up to nearest)
.towardZero
Équivalent à la trunc
fonction C.
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 le but de l'arrondi est de se préparer à travailler avec un entier (par exemple en utilisant Int
par FloatPoint
initialisation après arrondi), nous pourrions simplement utiliser le fait que lors de l'initialisation d'un en Int
utilisant a Double
(ou Float
etc), la partie décimale sera tronquée.
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
Équivalent à la ceil
fonction C.
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 pour FloatingPoint
vérifier l'équivalence des fonctions C aux différentes FloatingPointRoundingRule
règles
Si nous le souhaitons, nous pouvons jeter un œil au code source du FloatingPoint
protocole pour voir directement les équivalents de fonction C des FloatingPointRoundingRule
règles publiques .
Depuis swift / stdlib / public / core / FloatingPoint.swift.gyb, nous voyons que l'implémentation par défaut de la rounded(_:)
méthode nous fait de la round(_:)
méthode de mutation :
public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
var lhs = self
lhs.round(rule)
return lhs
}
Depuis swift / stdlib / public / core / FloatingPointTypes.swift.gyb, nous trouvons l'implémentation par défaut de round(_:)
, dans laquelle l'équivalence entre les FloatingPointRoundingRule
règles 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)
}
}
pow()
malheureusement pas disponible dans une aire de jeux