How to split a NSDecimalnumber between decimal & integer & back
-
20-08-2019 - |
Question
I can't figure how get the integral & decimal value from a NSDecimalnumber.
For example, if I have 10,5, how get 10 & 5?
And if I have 10 & 5, how return to 10,5?
Mmm ok, that is looking better!
However I have the concer about lossing decimals.
This is for a app that will be international. If for example a user set the price "124,2356" I wanna load & save the exact number.
Mmm ok, that is the way, but not respect the # of decimal places. If exist a way to know that from the current local I'm set.
This is because that represent currency values...
Solution
I'm using 2 for the scale since you said this was for currency but you may choose to use another rounding scale. I'm also ignoring any exceptions rounding may bring since this is a pretty simple example.
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
NSDecimalNumber *price = /* eg. 10.5 */;
NSDecimalNumber *dollars = [price decimalNumberByRoundingAccordingToBehavior: behavior];
NSDecimalNumber *cents = [price decimalNumberBySubtracting: dollars];
That will give you 10 and 0.5 in the dollars
and cents
variables respectively. If you want whole numbers you can use this method to multiply your cents
by a power of 10.
cents = [cents decimalNumberByMultiplyingByPowerOf10: 2];
Which will in turn multiply you cents
by 100, giving you 10 and 5 in dollars
and cents
. You should also know that you can use negative powers of 10 here to divide.
So,
cents = [cents decimalNumberByMultiplyingByPowerOf10: -2];
would undo that last method.
OTHER TIPS
Not sure what Math functions objective c has but something like
Math.floor(10.5) = 10
(10.5 - 10) * 10 = 5
bit of a clearer example (cos of the 10's)
Math.floor(20.4) = 20
(20.4 - 20) * 10 = 4;
The other problem
(5 / 10) = .5
10 + .5 = 10.5
The 10 used on the decimal points depends on the amount of decimal places... for instance
Math.floor(20.44) = 20
(20.44 - 20) * 100 = 44;
requires you to times by 100
If you don't have access to the math fns, this may work:
double val = [dn doubleValue]; // dn is a NSDecimalNumber*
int intPart = (int) val;
double doublePart = (val - intPart);
This may give you some trouble, the loop may never terminate, in that case you will have to put a counter in there:
while (doublePart != (int)doublePart) doublePart*=10;
double floor (double x);
is a POSIX function. This function can be used to find the highest integer value not greater than x
.
double x = 10.5;
double y = floor (x);
// y = 10.0
double z = x - y;
// z = 0.5