2010-08-24 6 views
7

L'uomo la roba più semplice mi sembra sempre così folle in Objective-C, comunque ho bisogno di fare alcune sottrazioni e moltiplicazioni di base e sono perplesso.problema di matematica di base con Numero intero e NSDecimalNumber - Operandi non validi in binario

ho:

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

sto semplicemente cercando di ottenere un NSDecimalNumber per visualizzare in questo modo:

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

Ho provato un sacco di diverse forme di questo e non riesco a capire cosa la diavolo sto sbagliando qui.

+0

Quale errore stai ottenendo? –

risposta

10

operatori standard non possono essere utilizzati con 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

Suggerirei di creare un NSDecimalNumber da un valore NSString di @ "100" per la prima riga, in per evitare errori di virgola mobile da insinuarsi. –

+0

La conversione da un int a un NSDecimalNumber è senza perdita anche con virgola mobile, in questo caso - 100 è direttamente rappresentabile da tutti i tipi primitivi, inclusi 'double' e' float'. –

3

NSDecimalNumber è un oggetto wrapper per un numero: lo si considera come un valore C. Invece, provare:

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

E 'confuso, ma NSNumber e NSDecimalNumber sono wrapper Objective-C per i tipi C, tipicamente utilizzati per lo stoccaggio in oggetti contenitore come NSArray (o Core dati). NSInteger e NSDecimal, d'altra parte, sono tipi C (NSInteger solo mappe per int).

MODIFICA: La risposta di falconcreek è migliore per evitare la perdita di precisione. Tuttavia, quando si utilizzano gli integer, in genere si utilizzano tipi C non archiviati.

+2

Rischio di perdita di precisione della conversione del prezzo al dettaglio in un float. Attenersi a 'NSDecimalNumber' – falconcreek

+0

destra di falconcreek, l'intero motivo per cui si desidera utilizzare un NSDecimalNumber per la valuta è di evitare errori in virgola mobile nei calcoli. Vedi la sua risposta per un modo più preciso di farlo. –

+0

Sì, sfortunatamente non c'è autoboxing in Objective-C. Una delle cose che mi manca di più da altre lingue. –

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

NSDecimalNumber è una classe. Quello che stai facendo qui è il calcolo di un valore e quindi l'assegnazione di quello per essere il valore di un puntatore a un oggetto NSDecimalNumber. Questo è un brutto mojo.

Non ho usato NSDecimalNumber prima, ma se avete bisogno di quel particolare oggetto, ciò che si vuole è qualcosa di simile:

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 è un'istanza di NSDecimalNumber che non funzionerà – falconcreek

Problemi correlati