2010-10-09 2 views
0

Je possède ce code:Ajout NSDecimalNumbers ne fonctionne pas tout à fait

NSLog(@"Count of items we will loop through is: %d",[self.defaultBudgetItemsArray count]); 
id object; 
while (object = [e nextObject]) { 
    if ([object objectForKey:@"actualCost"]) { 
     currentTotal = [currentTotal decimalNumberByAdding: [object objectForKey:@"actualCost"]]; 
     NSLog(@"decimalNumberByAdding gives: %@",[numberFormatter stringFromNumber:[currentTotal decimalNumberByAdding: [object objectForKey:@"actualCost"]]]); 
     NSLog(@"Trying to add: %@",[numberFormatter stringFromNumber:[object objectForKey:@"actualCost"]]); 
    } 
} 

totalActualCostLabel.text = [numberFormatter stringFromNumber:currentTotal]; 
NSLog(@"Budget items total: %@",[numberFormatter stringFromNumber:currentTotal]); 

La sortie de la console est:

2010-10-09 12:58:45.285 App[11659:307] Count of items we will loop through is: 6 
2010-10-09 12:58:45.287 App[11659:307] decimalNumberByAdding gives: ($0.00) 
2010-10-09 12:58:45.289 App[11659:307] Trying to add: $0.00 
2010-10-09 12:58:45.292 App[11659:307] decimalNumberByAdding gives: ($0.00) 
2010-10-09 12:58:45.293 App[11659:307] Trying to add: $0.00 
2010-10-09 12:58:45.296 App[11659:307] decimalNumberByAdding gives: ($0.00) 
2010-10-09 12:58:45.301 App[11659:307] Trying to add: $0.00 
2010-10-09 12:58:45.303 App[11659:307] decimalNumberByAdding gives: ($0.00) 
2010-10-09 12:58:45.305 App[11659:307] Trying to add: $5.00 
2010-10-09 12:58:45.307 App[11659:307] decimalNumberByAdding gives: ($0.00) 
2010-10-09 12:58:45.309 App[11659:307] Trying to add: $0.00 
2010-10-09 12:58:45.311 App[11659:307] decimalNumberByAdding gives: ($0.00) 
2010-10-09 12:58:45.318 App[11659:307] Trying to add: $0.00 
2010-10-09 12:58:45.320 App[11659:307] Budget items total: ($0.00) 

Notez que l'une des lignes "Essayer d'ajouter" dit $ 5.00 mais decimalnumberbyadding ne le fait pas semble faire son truc. Des idées?

Merci!

-Max

+0

Mes 2cents - utilisent des flotteurs. Il est beaucoup plus facile d'ajouter des structures spécifiques (comme int et float ou double) que d'utiliser NSNumber/NSDecimalNumber etc etc, et fonctionnera probablement. –

+10

Non, mon Dieu, s'il vous plaît, n'utilisez pas de flotteurs. Vous ne voulez jamais, jamais utiliser des nombres à virgule flottante pour représenter des devises (les erreurs d'arrondi peuvent vraiment gâcher votre programme!). Utilisez des entiers et représentez tout en centimes. –

+0

Montrez-nous où vous créez l'énumérateur et où vous déclarez currentTotal. – NSResponder

Répondre

1

Nous ne disposons pas d'informations assez pour vous aider à résoudre votre problème spécifique. Cela dit, j'ai essayé le code suivant à la vôtre initialiser:

NSArray *ary = [NSArray arrayWithObjects: 
    [NSDictionary dictionaryWithObject:[NSDecimalNumber decimalNumberWithString:@"0"] forKey:@"actualCost"], 
    [NSDictionary dictionaryWithObject:[NSDecimalNumber decimalNumberWithString:@"4"] forKey:@"actualCost"], 
    [NSDictionary dictionaryWithObject:[NSDecimalNumber decimalNumberWithString:@"5"] forKey:@"actualCost"], 
    [NSDictionary dictionaryWithObject:[NSDecimalNumber decimalNumberWithString:@"2"] forKey:@"actualCost"], nil]; 

NSEnumerator *e = [ary objectEnumerator]; 
NSDecimalNumber *currentTotal = [NSDecimalNumber zero]; 
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; 
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; 

Le code ci-dessus semble fonctionner sans drames, donc je vais devoir deuxième @ commentaire de NSResponder demandant votre code d'initialisation.

En outre, la ligne suivante de votre échantillon a (ce que je suppose être) un comportement inattendu:

NSLog(@"decimalNumberByAdding gives: %@",[numberFormatter stringFromNumber:[currentTotal decimalNumberByAdding: [object objectForKey:@"actualCost"]]]); 

Il ne provoque pas votre total est incorrecte, mais la sortie du journal sera trompeur. Au moment où la machine a atteint cette ligne, elle aura déjà ajouté la somme actuelle et votre journal la fera apparaître comme ayant été ajoutée deux fois. Je pense que vous voulez probablement les éléments suivants:

NSLog(@"decimalNumberByAdding gives: %@", [numberFormatter stringFromNumber:currentTotal]); 
+0

Exécutez votre code avec un nombre "999999999999999999" et il affichera "1000000000000000000". NSNumberFormatter convertit un argument en double avant le formatage :-( – Soonts

0

J'ai fini par aller avec la suggestion de itaiferber d'utiliser int est pour tout et ayant les données soient en cents. Semblait assez simple. Le code a fini comme:

- (void)totalBudgetItems { 
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; 
    [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; 
    [numberFormatter setCurrencySymbol:@"$"]; 
    [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; 
    NSInteger currentTotal = 0; 
    NSEnumerator *e = [self.defaultBudgetItemsArray objectEnumerator]; 
    NSLog(@"Count of items we will loop through is: %d",[self.defaultBudgetItemsArray count]); 
    id object; 
    while (object = [e nextObject]) { 
     if ([object objectForKey:@"actualCost"]) { 
      currentTotal = currentTotal + [[object objectForKey:@"actualCost"] intValue]; 
     } 
    } 
    NSNumber *tempDisplayTotalNumber = [NSNumber numberWithInt:currentTotal]; 
    totalActualCostLabel.text = [numberFormatter stringFromNumber:tempDisplayTotalNumber]; 
} 

Merci!

Questions connexes