Chiffres Arrondis NSDecimalNumber

j'ai du mal à comprendre quelque chose qui semble très simple. Je dois arrondir avec précision un NSDecimalNumber à un nombre précis de décimales (déterminé à l'exécution. Pour autant que je sache, j'ai deux options, aucune ne me plaît.

  1. Convertissez-vous en float, et utilisez les fonctions d'arrondi C: Je n'aime pas ça parce que la précision est importante dans ce cas. Les flotteurs ne peuvent pas toujours représenter avec précision les nombres décimaux, et ceci pourrait causer des problèmes.
  2. Convertissez en chaîne en utilisant NSNumberFormatter puis convertissez en arrière: je n'aime pas celui-ci car il semble juste laid et inefficace.

y a-t-il un autre moyen que j'ai manqué? Il y a suis pour être un moyen facile de faire l'arrondissement des nombres Nsdecimal, mais je ne semble pas pouvoir comprendre pour la vie de moi ce que c'est.

20
demandé sur Nate Thorn 2010-10-20 22:46:30

4 réponses

il Vous suffit d'appeler decimalNumberByRoundingAccordingToBehavior:avec les NSDecimalNumberBehaviors protocole. Voir le NSDecimalNumberBehaviors référence dans le dev docs.

Mise À Jour: Voir http://www.cimgf.com/2008/04/23/cocoa-tutorial-dont-be-lazy-with-nsdecimalnumber-like-me/

32
répondu CuriousRabbit 2012-12-13 01:15:43

pour ceux qui préfèrent le code d'exemple...

à arrondir à la deuxième décimale (12345.68):

NSDecimalNumber *originalNumber = [NSDecimalNumber decimalNumberWithString:@"12345.6789"];
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                                                          scale:2
                                                                               raiseOnExactness:NO
                                                                                raiseOnOverflow:NO
                                                                               raiseOnUnderflow:NO
                                                                            raiseOnDivideByZero:NO];

NSDecimalNumber *roundedNumber = [originalNumber decimalNumberByRoundingAccordingToBehavior:behavior];

Pour arrondir au millier le plus proche (12000):

NSDecimalNumber *originalNumber = [NSDecimalNumber decimalNumberWithString:@"12345.6789"];
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                                                          scale:-3
                                                                               raiseOnExactness:NO
                                                                                raiseOnOverflow:NO
                                                                               raiseOnUnderflow:NO
                                                                            raiseOnDivideByZero:NO];

NSDecimalNumber *roundedNumber = [originalNumber decimalNumberByRoundingAccordingToBehavior:behavior];
18
répondu Dave Batton 2015-11-29 19:38:07

Je l'ai fait fonctionner en utilisant le code ci-dessous dans Swift 3.

let amount = NSDecimalNumber(string: "123.456789")
let handler = NSDecimalNumberHandler(roundingMode: .plain, scale: 2, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false)
let roundedAmount = amount.rounding(accordingToBehavior: handler)

Notez le paramètre scale, utilisé pour définir les décimales dont vous avez besoin. Décrit ici: https://developer.apple.com/reference/foundation/nsdecimalnumberhandler/1578295-decimalnumberhandlerwithrounding

5
répondu Harry Bloom 2016-12-01 11:37:11

j'utilise cette solution:

import Foundation

extension NSDecimalNumber {
    public func round(_ decimals:Int) -> NSDecimalNumber {
        return self.rounding(accordingToBehavior:
            NSDecimalNumberHandler(roundingMode: .plain,
                                   scale: Int16(decimals),
                                   raiseOnExactness: false,
                                   raiseOnOverflow: false,
                                   raiseOnUnderflow: false,
                                   raiseOnDivideByZero: false))
    }
}

let amount = NSDecimalNumber(string: "123.456")

amount.round(2)  --> 123.46
amount.round(1)  --> 123.5
amount.round(0)  --> 123
amount.round(-1) --> 120
amount.round(-2) --> 100
0
répondu MarcioElizeu 2017-02-02 15:39:59