2010-08-24 7 views
7

El hombre las cosas más simples siempre me parecen tan locas en Objective-C, de todos modos tengo que hacer algunas restas y multiplicaciones básicas y estoy perplejo.problema matemático básico con enteros y NSDecimalNumber - operandos inválidos a binarios

que tengo:

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

Simplemente estoy tratando de conseguir un NSDecimalNumber para visualizar este modo:

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

he intentado un montón de diferentes formas de esto y no se puede averiguar cuál es el demonios estoy haciendo mal aquí.

+0

¿Qué error ¿estas pillando? –

Respuesta

10

operadores estándar no se pueden utilizar 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

Sugeriría crear un NSDecimalNumber a partir de un valor NSString de @ "100" para la primera línea, en para evitar que los errores de punto flotante se arrastren. –

+0

La conversión de un int a un NSDecimalNumber no tiene pérdidas incluso con punto flotante, en este caso - 100 es directamente representable por todos los tipos primitivos, incluyendo 'double' y' float'. –

3

NSDecimalNumber es un contenedor de objetos para un número; lo está tratando como un valor de C. En su lugar, trate de:

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

Es confuso, pero NSNumber y NSDecimalNumber son envolturas de Objective-C para los tipos C, que se utiliza normalmente para el almacenamiento de objetos contenedores tales como NSArray (o Core Data). NSInteger y NSDecimal, por otro lado, son tipos C (NSInteger solo mapas a int).

EDIT: La respuesta de falconcreek es mejor para evitar la pérdida de precisión. Sin embargo, cuando se trabaja con enteros, generalmente usará tipos de C no empaquetados.

+2

Riesgo de pérdida de la precisión al convertir el precio minorista en un flotador. Quédese con 'NSDecimalNumber' – falconcreek

+0

Falconcreek tiene razón, la razón por la que desea utilizar un NSDecimalNumber para moneda es evitar errores de punto flotante en sus cálculos. Vea su respuesta para una forma más precisa de hacer esto. –

+0

Sí, desafortunadamente no hay autoboxing en Objective-C. Una de las cosas que extraño más de otros idiomas. –

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

NSDecimalNumber es una clase. Lo que está haciendo aquí es calcular un valor y luego asignarlo para que sea el valor de un puntero a un objeto NSDecimalNumber. Este es un mal mojo.

No he utilizado NSDecimalNumber antes, pero si necesita ese particular objeto, lo que quiere es algo como esto:

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 es una instancia de NSDecimalNumber esto no funcionará – falconcreek