web-dev-qa-db-fra.com

Conversion décimale en double dans Swift 3

Je migre un projet de Swift 2.2 vers Swift 3 , et j'essaie de me débarrasser des anciens types de données Cocoa lorsque cela est possible.

Mon problème est ici: migrer NSDecimalNumber vers Decimal.

J'avais l'habitude de relier NSDecimalNumber à Double dans les deux sens dans Swift 2.2 :

let double = 3.14
let decimalNumber = NSDecimalNumber(value: double)

let doubleFromDecimal = decimalNumber.doubleValue

Maintenant, passez à Swift 3 :

let double = 3.14
let decimal = Decimal(double)

let doubleFromDecimal = ???

decimal.doubleValue n'existe pas, ni Double(decimal), pas même decimal as Double... Le seul piratage que je trouve est: 

let doubleFromDecimal = (decimal as NSDecimalNumber).doubleValue

Mais ce serait complètement stupide d'essayer de se débarrasser de NSDecimalNumber, et de devoir l'utiliser de temps en temps ...

Eh bien, soit j'ai raté quelque chose d'évident, et je vous demande pardon de perdre votre temps, ou bien il y a une lacune à résoudre, à mon avis ...

Merci d'avance pour votre aide.

Edit : Rien de plus sur le sujet sur Swift 4 .

24
Zaphod

Une autre solution qui fonctionne dans Swift 3 consiste à convertir la Decimal en NSNumber et à en créer la Double.

let someDouble = Double(someDecimal as NSNumber)
10
rmaddy

NSDecimalNumber et Decimal sont pontés

La superposition rapide du framework Foundation fournit le nombre décimal structure, qui relie à la classe NSDecimalNumber. La décimale type de valeur offre les mêmes fonctionnalités que NSDecimalNumber type de référence, et les deux peuvent être utilisés indifféremment dans le code Swift qui interagit avec les API Objective-C. Ce comportement est similaire à comment Swift établit un pont entre les types standard string, numeric et collection et leur classes de fondation correspondantes. Apple Docs

mais comme avec d'autres types pontés, certains éléments manquent.

Pour retrouver la fonctionnalité, vous pouvez écrire une extension:

extension Decimal {
    var doubleValue:Double {
        return NSDecimalNumber(decimal:self).doubleValue
    }
}

// implementation
let d = Decimal(floatLiteral: 10.65)
d.doubleValue
6
sketchyTech

Decimal dans Swift 3 n’est pas NSDecimalNumber . C'est NSDecimal , type complètement différent.

Vous devriez simplement continuer à utiliser NSDecimalNumber comme vous le faisiez auparavant.

3
user28434

Solution efficace dans Swift 4

let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = NSDecimalNumber(decimal: decimal).doubleValue
print(doubleFromDecimal)

Modifier: Sans NSDecimalNumber/NSNumber

let double = 3.14
let decimal = Decimal(double)
if let doubleFromDecimal = Double(decimal.description){
    print(doubleFromDecimal)
}
2
Pranavan Sp

Vous êtes censé utiliser l'opérateur as pour transtyper un type Swift en son type bridged sous-jacent Objective-C. Donc, utilisez simplement as comme ceci.

let p = Decimal(1)
let q = (p as NSDecimalNumber).doubleValue

Dans Swift 4, DecimalestNSDecimalNumber. Voici la citation de la documentation officielle d'Apple dans Xcode 10.

Important

La superposition Swift au framework Foundation fournit la Decimal structure, qui relie à la classe NSDecimalNumber. Pour plus Pour plus d'informations sur les types de valeur, voir Utilisation de frameworks Cocoa dans. Utilisation de Swift avec Cocoa et Objective-C (Swift 4.1).

Il n'y a plus de NSDecimal . Il y avait un type NSDecimal source de confusion dans Swift 3, mais cela semble être un bogue . Plus de confusion.

Remarque

Je vois que l'OP n'est pas intéressé par Swift 4, mais j'ai ajouté cette réponse car le fait de ne parler que de (obsolète) Swift 3 m'a rendu confus.

0
Eonil