4

I don't think a comprehensive, basic answer to this exists here yet, and googling didn't help.

Task: Given an NSDecimalNumber divide this by an int and return another NSDecimalNumber. Clarification: amount_text below must be converted to a NSDecimalNumber because it is a currency. The result must be a NSDecimalNumber, but I don't care what format the divisor is.

What I have so far:

// Inputs
NSString *amount_text = @"15.3";
int n = 10;

NSDecimalNumber *total = [NSDecimalNumber decimalNumberWithString:amount_text]; 

// Take int, convert to string. Take string, convert  to NSDecimalNumber.
NSString *int_string = [NSString stringWithFormat:@"%d", n];
NSDecimalNumber *divisor = [NSDecimalNumber decimalNumberWithString:int_string];
NSDecimalNumber *contribution = [total decimalNumberByDividingBy:divisor];

Surely, this can be done in a more straightforward way?

Unapiedra
  • 15,037
  • 12
  • 64
  • 93

4 Answers4

5

Is there any reason why you're using NSDecimalNumber? This can be done way easier like this:

// Inputs
NSString *amount_text = @"15.3";
int n = 10;

float amount = [amount_text floatValue];
float result = amount / n;

If you really want to do it with NSDecimalNumber:

// Inputs
NSString *amount_text = @"15.3";
int n = 10;

NSDecimalNumber *total = [NSDecimalNumber decimalNumberWithString:amount_text];
NSDecimalNumber *divisor = [NSDecimalNumber decimalNumberWithMantissa:n exponent:0 isNegative:NO];
NSDecimalNumber *contribution = [total decimalNumberByDividingBy:divisor];
DrummerB
  • 39,814
  • 12
  • 105
  • 142
4

You can always use initialisers when creating NSDecimalNumber. Since it is a subclass of NSNumber, NSDecimalNumber overrides initialisers.

So you can do

NSDecimalNumber *decimalNumber = [[NSDecimalNumber alloc] initWithInt:10];

however, you should be careful if your are doing high precision calculations as there are some problems using these initialisers. You can read about it here in more detail.

Community
  • 1
  • 1
mrt
  • 623
  • 4
  • 8
  • Which one is better: Your solution or DrummerB's (second) solution? Let's say my decimalNumber/divisor is between 1 and 10. – Unapiedra Dec 04 '13 at 11:31
  • Given the discussion in the linked question you should probably go with DrummerB's second solution `[NSDecimalNumber decimalNumberWithMantissa:n exponent:0 isNegative:NO];` – Felix Lamouroux Dec 04 '13 at 11:41
  • You get more precision with DrummerB's second solution, but you should be okay with inits as well. So it's up to you to decide, if you need more precision or not – mrt Dec 04 '13 at 11:48
1

Alternatively (potentially losing some precision):

double amount = 15.3;
double n = 10.0;
double contribution = amount / n;

// conversion to decimal
NSString *string = [NSString stringWithFormat:@"%f", n];
NSDecimalNumber *contribution_dec = [NSDecimalNumber decimalNumberWithString:string];

better yet (if n=10):

[dec decimalNumberByMultiplyingByPowerOf10:-1];
Felix Lamouroux
  • 7,414
  • 29
  • 46
  • Clarified my question: I need NSDecimalNumber. Great thinking with `decimalNumberByMultiplyingByPowerOf10` however I will have non-power of 10 divisors mostly. – Unapiedra Dec 04 '13 at 11:27
1

As per your code...

You are creating an NSDecimalNumber from string and then doing manipulations with it.

I never do that. Unless you need NSDecimalNumber unless you want a boxed Objective-C Object, Avoid it, use float and double.


If you want to do it much simpler you can do it as:

float quotient = [total floatValue]/n;

or,

float quotient = [contribution floatValue]/n;

EDIT: If you want with any specific reason to use boxed type then you can use as:

NSString *amount_text = @"15.3";
int n = 10;

NSDecimalNumber *total = [NSDecimalNumber decimalNumberWithString:amount_text];
NSDecimalNumber *divisor = [[NSDecimalNumber alloc] initWithInt:n];
NSDecimalNumber *contribution = [total decimalNumberByDividingBy:divisor];
Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
  • Clarification: I need to use NSDecimalNumber. – Unapiedra Dec 04 '13 at 11:29
  • Can I know the reason for that? as you are converting string to int, then decimal number again back to float/int and string... why this overhead? Anyways updated my answer to give you boxed type – Anoop Vaidya Dec 04 '13 at 11:30
  • I am having a user type in an amount using the numpad-keyboard. This I convert to `NSDecimalNumber total`, which I also need somewhere else. Here, I want to split the amount among n items. – Unapiedra Dec 04 '13 at 11:35