2010-08-24 6 views
7

L'homme le plus simple semble toujours si fou en Objective-C pour moi, de toute façon j'ai besoin de faire une soustraction et une multiplication de base et suis perplexe.problème mathématique de base avec Integer et NSDecimalNumber - opérandes invalides à binaire

J'ai:

client.PricingDiscount <-- this is an Integer 16 property on a CoreData NSManagedObject 
sku.RetailPrice <-- this is a Decimal property on a CoreData NSManagedObject 

Je suis tout simplement essayer d'obtenir un NSDecimalNumber pour afficher comme ceci:

NSDecimalNumber *showPrice = sku.RetailPrice * (100 - client.PricingDiscount); 

J'ai essayé un tas de différentes formes de cela et ne peut pas comprendre ce que le l'enfer je fais mal ici.

+0

Quelle erreur obtenez-vous? –

Répondre

10

opérateurs standard ne peuvent pas être utilisés avec NSDecimalNumber

NSDecimalNumber *one = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInt:100] decimalValue]]; 
NSDecimalNumber *factor = [one decimalNumberBySubtracting:[NSDecimalNumber decimalNumberWithDecimal:[client.PricingDiscount decimalValue]]]; 
NSDecimalNumber *showPrice = [sku.RetailPrice decimalNumerByMultiplying:factor]; 
+1

Je suggère de créer un NSDecimalNumber à partir d'une valeur NSString de @ "100" pour la première ligne, en –

+0

La conversion d'un int en un NSDecimalNumber est sans perte, même avec un flottant, dans ce cas - 100 est directement représentable par tous les types primitifs, y compris 'double' et' float'. –

3

NSDecimalNumber est un wrapper d'objet pour un nombre - vous le traitez comme une valeur C. Au lieu de cela, essayez:

float price = [sku.retailPrice floatValue] * (100 - [client.pricingDiscount floatValue]); 
NSDecimalNumber *showPrice = [NSDecimalNumber numberWithFloat:price]; 

Il est déroutant, mais NSNumber et NSDecimalNumber sont des emballages Objective-C pour les types C, généralement utilisés pour le stockage dans des objets conteneurs tels que NSArray (ou Core Data). NSInteger et NSDecimal, d'autre part, sont des types C (NSInteger juste des cartes à int).

EDIT: La réponse de falconcreek est mieux pour éviter la perte de précision. Lorsque vous travaillez avec des entiers, vous utiliserez généralement des types C non boxés.

+2

Risque de perte de précision lors de la conversion de RetailPrice en float. Stick avec 'NSDecimalNumber' – falconcreek

+0

falconcreek à droite, la raison pour laquelle vous souhaitez utiliser un NSDecimalNumber pour la monnaie est d'éviter les erreurs à virgule flottante dans vos calculs. Voir sa réponse pour une façon plus précise de le faire. –

+0

Oui, malheureusement, il n'y a pas d'autoboxing dans Objective-C. Une des choses qui me manque le plus des autres langues. –

0
NSDecimalNumber *showPrice = sku.RetailPrice * (100 - client.PricingDiscount); 

NSDecimalNumber est une classe. Ce que vous faites ici calcule une valeur, puis l'affecte à la valeur d'un pointeur sur un objet NSDecimalNumber. C'est un mauvais mojo.

Je ne l'ai pas utilisé NSDecimalNumber avant, mais si vous avez besoin de cet objet particulier, ce que vous voulez est quelque chose comme ceci:

NSNumber* number = [NSNumber numberWithFloat:(sku.RetailPrice * (100 - client.PricingDiscount))]; 
NSDecimal* decimal = [number decimalValue]; 
NSDecimalNumber* showPrice = [NSDecimalNumber decimalNumberWithDecimal:decimal]; 
+0

(sku.RetailPrice * (100 - client.PricingDiscount) -> RetailPrice est une instance de NSDecimalNumber cela ne fonctionnera pas – falconcreek