How do you get int and modulo (mod) divisions with NSDecimalNumber

I am confused by NSDecimalNumber and its "behavior". I have an NSDecimalNumber which is a dollar value, like $ 37.50 for example. I would like to know how many times to say that 5.0 is included in this number, and then find out what remains. I can get a direct division and get 7.50, but I want 7 mod 2.50. I could convert to an integer, but you need to keep the "cents", so I wonder if there are any tricks in the framework?

+6
objective-c cocoa-touch cocoa nsnumber
source share
4 answers

Using the 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]; 
+6
source share

Here is a NSDecimalNumber category that 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; } 
+5
source share
  • Divide the dividend by a divider, rounding down. It gives you the quotient.
  • Multiply the divisor by the quotient.
  • Subtract this from the dividend. It brings you back.

(37.50 // 5) == 7; 7 * 5 == 35; 37.50 - 35 = 2.50.

(Note: // is a Python operator for integral division. I borrowed it here. Obviously, you should not try to use // for division in Objective-C).

+4
source share

Theoretically, you can do some tricks using the NSDecimalNumber decimalNumberByDividingBy: decimalNumberByMultiplyingBy: and decimalValue . Divide the numbers, take the structure of the decimal numbers, determine the remainder of the structure, then create a new decimal number with this remainder and multiply the remaining by the original number.

An easier way to do this is probably to determine the maximum precision you want (name N places after the decimal point), multiply the number by 10eN, and then just take an integer value and split and mod it. However, you run the risk of losing data, especially with very large numbers, so check the largest amount you want and find out what type of data - if any - will work for you. NSNumber supports unsignedLongLongValue .

+1
source share

All Articles