I am confused by NSDecimalNumber and its "behaviors". I have an NSDecimalNumber that represents a dollar value, say $37.50. I'd like to find out how many times say 5.0 goes into that number and then know what's left over. I can get the straight division and get 7.50 but I want 7 mod 2.50. I could convert to an integer but need to save the "cents" so wondering if there's some tricks in the framework?
Using Peter Hoseys example, but with iOS code:
NSDecimalNumber *dividend = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:37.5] decimalValue]];
NSDecimalNumber *divisor = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:5.0] decimalValue]];
NSDecimalNumber *quotient = [dividend decimalNumberByDividingBy:divisor withBehavior:[NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]];
NSDecimalNumber *subtractAmount = [quotient decimalNumberByMultiplyingBy:divisor];
NSDecimalNumber *remainder = [dividend decimalNumberBySubtracting:subtractAmount];
(37.50 // 5) == 7; 7 * 5 == 35; 37.50 - 35 = 2.50.
(Note: //
is Python's operator for integral division. I've borrowed it here. Obviously, you should not actually attempt to use //
for division in Objective-C code.)
Here's a NSDecimalNumber
category which also works with negative numbers and negative divisors:
- (BOOL)isNegative
{
return (NSOrderedDescending == [[NSDecimalNumber zero] compare:self]);
}
- (NSDecimalNumber *)invertedNumber
{
NSDecimalNumber *negOne = [NSDecimalNumber decimalNumberWithMantissa:1 exponent:0 isNegative:YES];
return [self decimalNumberByMultiplyingBy:negOne];
}
- (NSDecimalNumber *)moduloFor:(NSDecimalNumber *)divisor
{
NSRoundingMode roundingMode = ([self isNegative] ^ [divisor isNegative]) ? NSRoundUp : NSRoundDown;
NSDecimalNumberHandler *rounding = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundingMode
scale:0
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO];
// divide and get the remainder
NSDecimalNumber *quotient = [self decimalNumberByDividingBy:divisor withBehavior:rounding];
NSDecimalNumber *subtract = [quotient decimalNumberByMultiplyingBy:divisor];
NSDecimalNumber *modulo = [self decimalNumberBySubtracting:subtract];
if ([divisor isNegative]) {
return [modulo invertedNumber];
}
return modulo;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With