Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

GuitarBoy18

macrumors newbie
Original poster
Aug 21, 2013
8
0
I want to format a number like 1,000,000,000 instead of 1000000000 in CS193P calculator based my version of calculator app. I did some research about similar question and other CS193P based calculators. Then I found answers that could be an answer of my question like these article.

- How to add commas to numbers? (MacRumors Forums)
https://forums.macrumors.com/threads/916491/

- NSNumberFormatter IOS Calculator display (Stack Overflow)
http://stackoverflow.com/questions/18025635/nsnumberformatter-ios-calculator-display

- NSNumberFormatter Class Reference (iOS Developer Library)
https://developer.apple.com/library...umberFormatter_Class/Reference/Reference.html

- NumberFormatters Data Formatting Guid (iOS Developer Library)
https://developer.apple.com/library...rmatting/Articles/dfNumberFormatting10_4.html

But problem is I don't know how it convert into my code.
Please give me an example or correct my code would be really appreciate.

How to formatting a number with thousands separator?

How to set limitation to display like display able to show up to 10 digits of number including floating point?

For example some number like 1,000.123456789, I want to show that number like 1,000.123457 instead of 1,000.123456789 or 1,000.123456 based on condition something like round up if the number is bigger than 10 digit including floating numbers.

My code is
Code:
- (IBAction)digitPressed:(UIButton *)sender {
    error.text = nil;

    NSString *digit = [[sender titleLabel] text];
    if (userIsInTheMiddleOfTypingANumber) {
        [display setText:[[display text] stringByAppendingString:digit]];
    } else {
        [display setText:digit];
        userIsInTheMiddleOfTypingANumber = YES;
    }
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setPositiveFormat:@",###"];
}
 
Probably the easiest way to enforce a ten digit limit would be to have an iVar counter that counts the number of times a digit is entered and ignores when the user attempts to enter more than 10 digits

As for the formatter... I'm not familiar with it so I'm just looking at the class reference and trying to help... I'm not sure if it's what is best for this situation or not. I think I would possibly just write a for loop that runs backwards over the string looking for the . and , characters, then skipping over 3 chars, checking if the next one is a , and adding one if it's not. Something like that.

I'm sure other people have other, probably better solutions.
 
Last edited:
This is what I wrote at some point when I needed numbers. Hope you'll find it usefull:

Code:
// -----------------------------------------------------------------------------
#pragma mark - Numbers
// -----------------------------------------------------------------------------

+ (NSString *)formatCurrencyValue:(double)value
{
   return ([self formatDecimalValue:value
                      decimalPlaces:2
                       showCurrency:NO
                              group:YES
                           showZero:NO]);
}

+ (NSString *)formatCurrencyValue:(double)value
                     showCurrency:(BOOL)showCurrency
                         showZero:(BOOL)showZero
{
   return ([self formatDecimalValue:value
                      decimalPlaces:2
                       showCurrency:showCurrency
                              group:YES
                           showZero:showZero]);
}

+ (NSString *)formatDecimalValue:(double)value
                   decimalPlaces:(int)decPlc
                    showCurrency:(BOOL)showCurrency
                           group:(BOOL)groupByThousend
                        showZero:(BOOL)showZero
{
   NSNumberFormatter  *numberFormatter = [[NSNumberFormatter alloc] init];

   [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
   // [numberFormatter setCurrencySymbol:@"$"];
   [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];  // NSNumberFormatterCurrencyStyle
   if (groupByThousend)
      [numberFormatter setUsesGroupingSeparator:YES];

   [numberFormatter setMinimumFractionDigits:decPlc];
   [numberFormatter setMaximumFractionDigits:decPlc];

   [numberFormatter setLocale:[NSLocale currentLocale]];

   NSNumber  *c = [NSNumber numberWithFloat:value];

   // NSLog (@"Currency symbol   : %@", numberFormatter.currencySymbol);
   // NSLog (@"Currency separator: %@", numberFormatter.currencyGroupingSeparator);

   NSLog (@"Currency padding: %d", numberFormatter.paddingPosition);


   NSString  *retStr = [numberFormatter stringFromNumber:c];

   if (!showZero && ([retStr isEqual:@"0,00"] || [retStr isEqual:@"0.00"]))
      return (@"");

   if (showCurrency)
      return ([NSString stringWithFormat:@"%@ %@", retStr, numberFormatter.currencySymbol]);

   return (retStr);
}

Notice that the code is for ARC and that the currency symbol is placed after the value. Feel free to change anything and experiment.
 
Last edited:
Thanks for your reply and sample code!

I edit my code something like this. It's no error but "," doesn't appear on calculator display. I think these numberFormatter things are yet not hocked up with text. If you can correct this code, that would be awesome.

Code:
    - (IBAction)digitPressed:(UIButton *)sender {
    error.text = nil;
        
        NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
        [numberFormatter setUsesGroupingSeparator:YES];
        [numberFormatter setGroupingSize:3];
        [numberFormatter setGroupingSeparator:@","];
        [numberFormatter setMaximumFractionDigits:10];
    
        NSString *digit = [[sender titleLabel] text];
    
        //NSLog(@"digit pressed = %@", digit);
        
        if (userIsInTheMiddleOfTypingANumber) {
            [display setText:[[display text] stringByAppendingString:digit]];
        } else {
            [display setText:digit];
            userIsInTheMiddleOfTypingANumber = YES;
            
        }
        
    }

Thanks!
 
You're not really using the formatter.

Can't say what is userIsInTheMiddleOfTypingANumber, but when you append the last digit, put somewhere these two lines:

Code:
   NSNumber  *c = [numberFormatter numberFromString:display.text];

   display.text = [numberFormatter stringFromNumber:c];
 
It's works!!

Thanks your help my friend! I put those lines in my code like this:

Code:
- (IBAction)digitPressed:(UIButton *)sender {
    error.text = nil;
    
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    
    NSString *digit = [[sender titleLabel] text];
    //NSLog(@"digit pressed = %@", digit);
    

    if (userIsInTheMiddleOfTypingANumber) {
        [display setText:[[display text] stringByAppendingString:digit]];
        
        
        NSNumber  *c = [numberFormatter numberFromString:display.text];
        display.text = [numberFormatter stringFromNumber:c];
        
        
    } else {
        [display setText:digit];
        userIsInTheMiddleOfTypingANumber = YES;
        
    }
}

And a number like 1000 convert to 1,000!! This is awesome!
But when I enter 5th digit right after 1,000, display goes to empty. Then I notice display has got limitation up to 4 digit available somehow.

Now I'm searching how to figure it out. At same time I would like to continue to receiving your help or hint, if you have time for it.

BTW, custom class "userIsInTheMiddoleOfTypingANumber" is set for erase 0 thats shows up on display from the begging in my understanding.

Thank you again. This is certainly moving forward by your help.
 
Now display became able to show bigger than 4 digit with thousands separator but..

Here is my update.

Display now able to show number with thousands separator which enter by digitPressed action. Then I want to same number format for operationPressed action. I've add those lines to operationPressed section. But this time when I pressed operation button after enter number by pressed digit button, numbers after thousands separator erased. For example I enter number like 100000 and then display shows number as 100,000. After that I press operation button like +, the number become 100 instead of 100,000 and then enter some number like 1 and equal button, display shows result as 101.

Code:
- (IBAction)operationPressed:(UIButton *)sender
{
    //
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    //

    if(userIsInTheMiddleOfTypingANumber){
        self.model.operand = [display.text doubleValue];
        userIsInTheMiddleOfTypingANumber = NO;
    }

    NSString *operation = [[sender titleLabel] text];
    [self.model performOperation:operation];
    NSNumber  *c = [numberFormatter numberFromString:display.text];
    display.text = [numberFormatter stringFromNumber:c];
    display.text = [NSString stringWithFormat:@"%.12g", self.model.operand];

I think I don't wired up numberFormatter and operand yet. But problem is I don't know how to do it. I'm keep trying figure it out now. But if anyone knows how to do it or find problem in these code, please let me know it.
Thanks,
 
Last edited:
You can't use [display.text doubleValue] sometimes and formatter other times. You must use formatter for all conversions from text to numbesrs and back.
 
Thanks!

Thanks for your comment. That's make sense. I really don't understand C syntax yet. So I'm searching sample code. If I can't find something like that, better would learn syntax.
 
Isn't this a gross violation of MVC?

Shouldn't he have a number variable (say, a double?) which is directly modified when the keys are pressed and then separately have an NSString which is displayed and whose value is always the double run through a formatter?
 
Oh snap!

Yeah number value is double. And snap! That is calculator model. I don't put number formatter in my calculator model itself yet. I'm gonna do that.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.