Pourquoi l'arrondi des Double en Swift est un casse-tête (et comment y faire face en 2025)
Tout développeur iOS rencontre tôt ou tard cette situation : il doit afficher à l'utilisateur le prix d'un article 99.99, mais dans le code, c'est 99.99000000000001. Ça vous dit quelque chose ? Bienvenue dans le monde de l'arrondi des Double en Swift — un sujet qui a cumulé des milliers de vues sur Stack Overflow et continue d'agiter les esprits même en 2025.
Le problème ne vient pas de Swift — il vient de la nature même des nombres à virgule flottante (IEEE 754). Un Double ne peut pas représenter exactement 0.1, tout comme 1/3 en système décimal. Mais pour l'utilisateur, ce n'est pas une excuse. Il veut de beaux chiffres à l'écran.
Dans cet article, je vais vous montrer 5 méthodes éprouvées pour arrondir un Double en Swift, analyser leurs avantages et inconvénients, et vous donner un algorithme clair pour choisir selon votre besoin. C'est parti !
Méthode 1 : Foundation — round() + pow(10, n) — le classique du genre
La méthode la plus évidente qui vient à l'esprit : multiplier le nombre par 10^n, arrondir, diviser à nouveau.
import Foundation
func roundDouble(_ value: Double, toPlaces places: Int) -> Double { let divisor = pow(10.0, Double(places)) return round(value * divisor) / divisor}
let price = 99.995print(roundDouble(price, toPlaces: 2)) // 100.0 (arrondi bancaire)Avantages :
- Simplicité et lisibilité
- Fonctionne « prêt à l'emploi » — pas d'imports supplémentaires nécessaires
Inconvénients :
- Erreurs de précision — à cause du Double, on peut obtenir 99.99000000000001 au lieu de 99.99
- Problème avec l'arrondi bancaire — round() utilise l'arrondi half up, ce qui n'est pas toujours adapté aux finances
- pow(10, n) — des calculs superflus
Cette méthode convient pour un arrondi grossier dans l'interface utilisateur, mais pas pour les calculs financiers.
Méthode 2 : String(format:) — arrondi via une chaîne (le plus rapide pour l'interface utilisateur)
Si votre objectif final est d'afficher un nombre à l'écran, pourquoi travailler avec un Double ? Transformez-le directement en chaîne.
let value = 123.456789let roundedString = String(format: "%.2f", value)print(roundedString) // "123.46"
// Retour en Double (si nécessaire)let roundedDouble = Double(roundedString) ?? 0.0Avantages :
- Vitesse fulgurante — pas d'opérations mathématiques superflues
- Nombre de décimales garanti correct en sortie
- Prise en charge de la localisation (séparateur décimal)
Inconvénients :
- Le résultat est une chaîne, pour des calculs ultérieurs, il faut reconvertir (perte de précision)
- Ne convient pas pour l'arrondi bancaire (arrondi half up par défaut)
Idéal pour l'affichage des prix, pourcentages, évaluations — partout où une précision de ±0.01 n'est pas critique.
Méthode 3 : NSDecimalNumber — le roi de la précision financière
Quand il s'agit d'argent, le Double est un mal. Utilisez NSDecimalNumber — il stocke les nombres au format décimal sans erreurs d'arrondi.
import Foundation
func roundDecimal(_ value: Double, toPlaces places: Int, roundingMode: NSDecimalNumber.RoundingMode = .plain) -> Double { let decimal = NSDecimalNumber(value: value) let handler = NSDecimalNumberHandler( roundingMode: roundingMode, scale: Int16(places), raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false ) return decimal.rounding(accordingToBehavior: handler).doubleValue}
let amount = 99.995print(roundDecimal(amount, toPlaces: 2, roundingMode: .bankers)) // 99.99 (arrondi bancaire !)Avantages :
- Contrôle total sur l'arrondi — .plain, .down, .up, .b