views:

233

answers:

2

ExclusivePrice, quantity are both NSDecimalNumbers.

NSDecimalNumber *price = [exclusivePrice decimalNumberByMultiplyingBy:quantity];
NSLog(@"%@ * %@ = %@", exclusivePrice, quantity, price);

The result I get:

2010-04-05 00:22:29.111 TestApp[13269:207] 65 * 2 = -0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007169919476068871316457914368

What I expected:

2010-04-05 00:22:29.111 TestApp[13269:207] 65 * 2 = 130

Can anyone explain this please?

Edit:

Full repro:

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSDecimalNumber *n2 = (NSDecimalNumber *)[formatter numberFromString:@"2"];
NSDecimalNumber *n1 = (NSDecimalNumber *)[NSDecimalNumber numberWithInt:65];
NSDecimalNumber *n3 = [n1 decimalNumberByMultiplyingBy:n2];
NSLog(@"%@ * %@ = %@", n1, n2, n3);
+1  A: 

Seems to work for me.

NSDecimalNumber * n1 = [NSDecimalNumber decimalNumberWithString:@"65"];
NSDecimalNumber * n2 = [NSDecimalNumber decimalNumberWithString:@"2"];

NSDecimalNumber * res = [n1 decimalNumberByMultiplyingBy:n2];

NSLog(@"%@ * %@ = %@", n1, n2, res);

Output:

2010-04-05 08:40:42.812 x[24301] 65 * 2 = 130
stefanB
Yeah I'm baffled. I tried the same thing now in a different project and it works for me too. Somehow this is not working for me in the project where it matters.
rein
How do you initialize those values in the project where it fails?
stefanB
I've added the full repro in my question. I'm presuming that there's something wrong in casting from the formatter?
rein
When you use `NSNumberFormatter` it returns `NSNumber` object which is not the same as `NSDecimalNumber`. Looking at ref `NSNumber` does not define any arithmetic operations so if it is possible use `NSDecimalNumber`'s `decimalNumberWithString` to get the correct object to be passed later to `decimalNumberByMultiplyingBy` which expects `NSDecimalNumber` object.
stefanB
Thanks Stefan. I assumed since NSNumber was a superclass of NSDecimalNumber I could simply cast in the assignment. The cast kinda works (as is evident by the NSLog) but causes these kind of strange problems later on.
rein
+1  A: 

I found the answer: According to http://stackoverflow.com/questions/453691/how-use-nsdecimalnumber I can't easily convert between NSNumber and NSDecimalNumber. To convert from the one to the other I have to do :

NSDecimalNumber *n2 = [NSDecimalNumber decimalNumberWithDecimal:
                              [[formatter numberFromString:@"2"] decimalValue]];

It would have been nice if the NSNumberFormatter had a decimalNumberFromString: method.

rein
I was just looking at it. It seems that NSNumber is used for formatting and simple comparison and NSDecimalNumber in arithmetic operations using decimal numbers. So while you can create NSDecimalNumber from string you can't create it from a double or float but you can create NSNumber from int or float ...
stefanB