Reputation: 438
I've seen a similar topic about this a while back, but that seemed to be because the equation used NSNumber somewhere. I've checked all my code and all I can see is that I'm using NSDecimalNumbers for my equations.
I got a JSON webservice that returns some pricing numbers.
Just after parsing them in object properties I want to run the following equation with them:
NetPrice * ( 1 + (RawPercentage / 100)) + FixedPrice = processedNetPrice
Update: I changed the code to this:
NSDecimalNumber *one = [NSDecimalNumber one];
if (!self.netPrice || [self.netPrice isKindOfClass:[NSNull class]])
{ self.netPrice = [NSDecimalNumber zero]; }
NSDecimalNumber *nettoPrijs = self.netPrice;
NSLog(@"self.netPrice = %@",self.netPrice);
//Returns: self.netPrice = 89.25
NSLog(@"nettoPrijs = %@",nettoPrijs);
//Returns: nettoPrijs = 89.25
if (!self.userData.BandFixed || [self.userData.BandFixed isKindOfClass:[NSNull class]])
{ self.userData.BandFixed = [NSDecimalNumber zero]; }
NSDecimalNumber *fixedPrice = self.userData.BandFixed;
NSLog(@"self.userData.BandFixed = %@",self.userData.BandFixed);
//Returns: self.userData.BandFixed = 0
NSLog(@"fixedPrice = %@",fixedPrice);
//Returns: fixedPrice = 0
if (!self.userData.BandPercentage || [self.userData.BandPercentage isKindOfClass:[NSNull class]])
{ self.userData.BandPercentage = [NSDecimalNumber zero]; }
NSDecimalNumber *rawPercentage = self.userData.BandPercentage;
NSLog(@"self.userData.BandPercentage = %@",self.userData.BandPercentage);
//Returns: self.userData.BandPercentage = 0
NSLog(@"rawPercentage = %@",rawPercentage);
//Returns: rawPercentage = 0
NSDecimalNumber *percentage = [rawPercentage decimalNumberByMultiplyingByPowerOf10:-2];
NSLog(@"percentage = %@",percentage);
//Returns: percentage = 0
NSDecimalNumber *onePercent = [one decimalNumberByAdding:percentage];
NSLog(@"onePercent = %@",onePercent);
//Returns: onePercent = 1
NSDecimalNumber *onePercentTimesNetPrice = [onePercent decimalNumberByMultiplyingBy:nettoPrijs];
NSLog(@"onePercentTimesNetPrice = %@",onePercentTimesNetPrice);
//Returns: onePercentTimesNetPrice =
-0.000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000359498933794611654993903616
NSDecimalNumber *addingFixed = [onePercentTimesNetPrice decimalNumberByAdding:fixedPrice];
NSLog(@"addingFixed = %@",addingFixed);
//Returns: addingFixed =
-0.000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000359498933794611654993903616
If I change:
NSDecimalNumber *onePercentTimesNetPrice = [onePercent decimalNumberByMultiplyingBy:nettoPrijs];
to:
NSDecimalNumber *onePercentTimesNetPrice = [nettoPrijs decimalNumberByMultiplyingBy:onePercent];
it crashes:
-[__NSCFNumber decimalNumberByMultiplyingBy:]: unrecognized selector sent to instance 0x84ad160
Upvotes: 0
Views: 1320
Reputation: 438
I fixed it using:
- (void) doMath
{
NSDecimalNumber *one = [NSDecimalNumber one];
NSLog(@"Band: %@ one = %@",self,one);
if (!self.netPrice || [self.netPrice isKindOfClass:[NSNull class]]) { self.netPrice = [NSDecimalNumber zero]; }
NSDecimalNumber *nettoPrijs = self.netPrice;
NSLog(@"self.netPrice = %@",self.netPrice);
NSLog(@"nettoPrijs = %@",nettoPrijs);
if (!self.userData.BandFixed || [self.userData.BandFixed isKindOfClass:[NSNull class]]) { self.userData.BandFixed = [NSDecimalNumber zero]; }
NSDecimalNumber *fixedPrice = self.userData.BandFixed;
NSLog(@"self.userData.BandFixed = %@",self.userData.BandFixed);
NSLog(@"fixedPrice = %@",fixedPrice);
if (!self.userData.BandPercentage || [self.userData.BandPercentage isKindOfClass:[NSNull class]]) { self.userData.BandPercentage = [NSDecimalNumber zero]; }
NSDecimalNumber *rawPercentage = self.userData.BandPercentage;
NSLog(@"self.userData.BandPercentage = %@",self.userData.BandPercentage);
NSLog(@"RawPercentage = %@",rawPercentage);
NSDecimalNumber *percentage = [rawPercentage decimalNumberByMultiplyingByPowerOf10:-2];
NSLog(@"percentage = %@",percentage);
NSDecimalNumber *onePercent = [one decimalNumberByAdding:percentage];
NSLog(@"onePercent = %@",onePercent);
NSDecimalNumber gertje = [NSDecimalNumber decimalNumberWithDecimal:nettoPrijs.decimalValue]; * NSDecimalNumber *onePercentTimesNetPrice = [gertje decimalNumberByMultiplyingBy:onePercent];
NSLog(@"onePercentTimesNetPrice = %@",onePercentTimesNetPrice);
NSDecimalNumber *addingFixed = [onePercentTimesNetPrice decimalNumberByAdding:fixedPrice];
NSLog(@"addingFixed = %@",addingFixed);
}
Thanks for all your help!
Upvotes: 0
Reputation: 539745
As your NSLog() output shows, self.userData.RawPercentage
and self.userData.FixedPrice
are nil
, i.e. are not allocated + initialized as NSDecimalNumber
objects.
nil
cannot be used to represent the decimal number zero!
In fact, when I try your code,
NSDecimalNumber *custPrice1 = [oneWithNet decimalNumberByAdding:priceFixed];
crashes because priceFixed
is nil.
So you should check the code where these variables are initialized and make sure that they point to valid NSDecimalNumber
objects.
UPDATE: The error message
-[__NSCFNumber decimalNumberByMultiplyingBy:]: unrecognized selector sent to instance 0x84ad160
shows that nettoPrijs
is a NSNumber
object and not a NSDecimalNumber
. The following simplified code shows what happens if you try to multiply a NSDecimalNumber
with a NSNumber
:
NSDecimalNumber *one = [NSDecimalNumber one];
id price = [NSNumber numberWithFloat:89.25];
NSDecimalNumber *product = [one decimalNumberByMultiplyingBy:price];
NSLog(@"product = %@", product);
// Output:
// product = -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000221166721562906606351581184
(I have no idea why this doesn't crash or produce some error message.)
It works correctly if you multiply with a NSDecimalNumber
:
price = [NSDecimalNumber decimalNumberWithString:@"89.25"];
product = [one decimalNumberByMultiplyingBy:price];
NSLog(@"product = %@", product);
// Output:
// product = 89.25
So I assume that self.netPrice
is a NSNumber
object which has to be converted to a NSDecimalNumber
. The same may apply to the other number objects.
Upvotes: 1