How can i display the number in such a format? - objective-c

I am displaying a number in textfield. Which displays the number as "1234" but i want to display it as in format of "1,234" if i enter another large number which displays as "12345" but i want to display it as "12,345" if i enter 123456 which has to display as "123,456" . How do I format this number in desired format?
-(void)clickDigit:(id)sender
{
NSString * str = (NSString *)[sender currentTitle];
NSLog(#"%#",currentVal);
if([str isEqualToString:#"."]&& !([currentVal rangeOfString:#"."].location == NSNotFound) )
{
return;
}
if ([display.text isEqualToString:#"0"])
{
currentVal = str;
[display setText:currentVal];
}
else if([currentVal isEqualToString:#"0"])
{
currentVal=str;
[display setText:currentVal];
}
else
{
if ([display.text length] <= MAXLENGTH)
{
currentVal = [currentVal stringByAppendingString:str];
NSLog(#"%#",currentVal);
[display setText:currentVal];
}
currentVal=display.text;
}
}
This is the code i am using to display the number in textfield.
EDIT: I Changed my code into the following but still don't get the number correctly formatted:
if ([display.text length] <= MAXLENGTH) {
currentVal = [currentVal stringByAppendingString:str];
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *tempNum = [myNumFormatter numberFromString:currentVal];
NSLog(#"My number is %#",tempNum);
[display setText:[tempNum stringValue]];
currentVal=display.text;
}

You can do it like this:
int myInt = 12345;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *number = [NSNumber numberWithInt:myInt];
NSLog(#"%#", [formatter stringFromNumber:number]); // 12,345
Edit
You didn't implement this correctly, the key is to obtain the string representation of the number using [formatter stringFromNumber:number], but you didn't do that. So change your code into:
currentVal = [currentVal stringByAppendingString:str];
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *tempNum = [myNumFormatter numberFromString:currentVal];
NSLog(#"My number is %#",tempNum);
[display setText:[myNumFormatter stringFromNumber:tempNum]]; // Change this line
currentVal=display.text;
NSLog(#"My formatted number is %#", currentVal);

First, read through the list of methods on the NSNumberFormatter reference page. After doing that, you'll probably realize that you need to use the -setHasThousandSeparators: method to turn on the thousand separators feature. You can also use the -setThousandSeparator: method to set a custom separator, though you probably won't need to do that.

Related

Convert a string to a positive or negative number

I am new to ObjC. I've spent years working in Applescript and I've decided to move up. I am a hobbiest programmer.
I have the following code:
+(NSArray *) initArrayWithFileContents:(NSString *) theFilePath
{
NSString *theContents = [(self) loadFile:theFilePath]; // returns the contents of a text file
NSArray *theParagraphs = [(self) getParagraphs:theContents]; // returns the contents as an array of paragraphs
NSMutableArray *teamData = [[NSMutableArray alloc] init]; // array of team data
NSMutableArray *leagueData = [[NSMutableArray alloc] init]; // array of arrays
NSNumberFormatter *numberStyle = [[NSNumberFormatter alloc] init];
[numberStyle setNumberStyle:NSNumberFormatterDecimalStyle];
for (NSString *currentParagraph in theParagraphs)
{
NSArray *currentTeam = [(self) getcolumnarData:currentParagraph];
for (NSString *currentItem in currentTeam)
{
NSNumber *currentStat = [numberStyle numberFromString:currentItem];
if (currentStat != Nil) {
[teamData addObject:currentStat];
} else {
[teamData addObject:currentItem];
}
}
[leagueData addObject:teamData];
[teamData removeAllObjects];
}
return leagueData;
}
This works fine for strings and for negative numbers, but a number preceded by a "+" sign is returned as a string. I figure I need to use a different number formatter style but I don't know what to use.
Thanks in advance,
Brad
NSNumberFormatter *numberStyle = [[NSNumberFormatter alloc] init];
[numberStyle setNumberStyle:NSNumberFormatterDecimalStyle];
[numberStyle setPositiveFormat:#"'+'#"] ;
or
NSNumberFormatter *numberStyle = [[NSNumberFormatter alloc] init];
[numberStyle setNumberStyle:NSNumberFormatterDecimalStyle];
[numberStyle setPositivePrefix:#"+"] ;
You could remove the + sign if one exists:
if ([currentItem hasPrefix:#"+"])
{
currentItem = [currentItem substringWithRange:NSMakeRange(1, [currentItem length] -1)];
}
Probably a better way, but this would work.
What ended up working for me was to create 2 NSNumberFormatters; 1 for decimals and 1 for decimals using the setPositiveFormat: method as described above. If the first formatter doesn't work, it'll flow on to the next formatter using the positive format.

NSNumberFormatter unable to allow numbers to start with a 0

So I'm attempting to automatically add slashes between 2 digits when a user enters in their birthday, but for some reason when the birthday starts with a 0, the number formatter erases it and messes up the birthday. I've got my code below, could someone help me figure out how to do this? Thanks in advance!
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init] ;
[formatter setGroupingSeparator:#"/"];
[formatter setGroupingSize:2];
[formatter setUsesGroupingSeparator:YES];
[formatter setSecondaryGroupingSize:2];
NSString *num = textField.text ;
if(![num isEqualToString:#""])
{
num= [num stringByReplacingOccurrencesOfString:#"/" withString:#""];
NSString *str = [formatter stringFromNumber:[NSNumber numberWithDouble:[num doubleValue]]];
textField.text=str;
}
What you could do is the following:
Check the length of the string
If length mod 2 == 0 then add "/"
Log your string
I'm not saying this is recommended but it might help you a bit!
- (void)controlTextDidChange:(NSNotification *)obj{
NSString *num = [textField stringValue] ;
if (num.length%2==0)
{
NSString *someText = [NSString stringWithFormat: #"%#/ ", num];
num = someText;
}
textField.stringValue = num;
}
Something like this may help:
NSMutableString *string = #"YOUR TEXTFIELD TEXT";
NSString *lastString = [string substringWithRange:NSMakeRange(string.length-2, 1)];
if ([lastString isEqualToString:#"/"]) {
return;
}
if (string.length == 2 || string.length == 5) {
[string appendString:#"/"];
}

NSNumberFormatter currency remove trailing zeros

I want to format prices like 45.50 but I don't want prices like 45.00. How can I avoid this?
I did it this way:
NSNumber *amount = #(50.5);
NSNumberFormatter *currencyFormat = [[NSNumberFormatter alloc] init];
[currencyFormat setNumberStyle:NSNumberFormatterCurrencyStyle];
[currencyFormat setLocale:[NSLocale currentLocale]];
if (trunc(amount.floatValue) == amount.floatValue) {
[currencyFormat setMaximumFractionDigits:0];
} else {
[currencyFormat setMaximumFractionDigits:2];
}
NSLog(#"%#", [currencyFormat stringFromNumber:amount]);
I like this solution for its simplicity. Output will be $50.50. And for amount = #(50.0) will be $50
Do this:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2];
[formatter setRoundingMode: NSNumberFormatterRoundUp];
NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:22.368511]];
NSLog(#"Result...%#",numberString);//Result 22.37
Now trail unwanted like this:
NSString* CWDoubleToStringWithMax2Decimals(double d) {
NSString* s = [NSString stringWithFormat:#"%.2f", d];
NSCharacterSet* cs = [NSCharacterSet characterSetWithCharacterInString:#"0."];
NSRange r = [s rangeOfCharacterInSet:cs
options:NSBackwardsSearch | NSAnchoredSearch];
if (r.location != NSNotFound) {
s = [s substringToIndex:r.location];
}
return s;
}
If you're just after a very quick and dirty hack . . .
// Get the price as a string
NSString *priceString = [NSString stringWithFormat:#"%2.2f", priceFloat];
// Trim if needed
if ([priceString hasSuffix:#".00"])
priceString = [priceString substringToIndex:priceString.length-3];
NB This method won't work for localised content i.e. In Europe the decimal separator is a comma so you will see 45,00, not 45.00.
float myOriginalPrice = 45.50;
CGFloat mod = fmod(myOriginalPrice, 1);
if (mod == 0){
mod = (int)myOriginalPrice;
NSLog(#"%.0f", mod);
} else {
NSLog(#"%f", myOriginalPrice);
}
INPUT : 12.74 OR 12.745
NSString *inputString=[NSString string];
inputString=[NSString stringWithFormat:#"%.4g",12.74f];
NSLog(#"inputString : %# \n\n",inputString);
OUTPUT:
inputString : 12.74
INPUT : 12.00 OR 12.000
NSString *inputString=[NSString string];
inputString=[NSString stringWithFormat:#"%.4g",12.00f];
NSLog(#"inputString : %# \n\n",inputString);
OUTPUT:
inputString : 12
UPDATED ANSWER: for his comment question
INPUT:12.30
i assume here he is going to show this value in some UI like UILabel,.....Not For Calculation.
NSString *inputString=[NSString string];
inputString=[NSString stringWithFormat:#"%.4g",12.30f];
NSArray *arr=[inputString componentsSeparatedByString:#"."];
if ([arr count] >= 2) {
NSString *secondStr=[arr objectAtIndex:1];
if ([secondStr length]<2) {
inputString=[NSString stringWithFormat:#"%#0",inputString];
}
}
NSLog(#"inputString : %# \n\n",inputString);
OUTPUT:
inputString : 12.30

Limiting both the fractional and total number of digits when formatting a float for display

I need to print a float value in area of limited width most efficiently. I'm using an NSNumberFormatter, and I set two numbers after the decimal point as the default, so that when I have a number like 234.25 it is printed as is: 234.25. But when I have 1234.25 I want it to be printed as: 1234.3, and 11234.25 should be printed 11234.
I need a maximum of two digits after the point, and a maximum of five digits overall if I have digits after the point, but it also should print more than five digits if the integer part has more.
I don't see ability to limit the total number of digits in NSNumberFormatter. Does this mean that I should write my own function to format numbers in this way? If so, then what is the correct way of getting the count of digits in the integer and fractional parts of a number? I would also prefer working with CGFLoat, rather than NSNumber to avoid extra type conversions.
You're looking for a combination of "maximum significant digits" and "maximum fraction digits", along with particular rounding behavior. NSNumberFormatter is equal to the task:
float twofortythreetwentyfive = 234.25;
float onetwothreefourtwentyfive = 1234.25;
float eleventwothreefourtwentyfive = 11234.25;
NSNumberFormatter * formatter = [[NSNumberFormatter alloc] init];
[formatter setUsesSignificantDigits:YES];
[formatter setMaximumSignificantDigits:5];
[formatter setMaximumFractionDigits:2];
[formatter setRoundingMode:NSNumberFormatterRoundCeiling];
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:twofortythreetwentyfive]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:onetwothreefourtwentyfive]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:eleventwothreefourtwentyfive]]);
Result:
2012-04-26 16:32:04.481 SignificantDigits[11565:707] 234.25
2012-04-26 16:32:04.482 SignificantDigits[11565:707] 1234.3
2012-04-26 16:32:04.483 SignificantDigits[11565:707] 11235
Code :
#define INTPARTSTR(X) [NSString stringWithFormat:#"%d",(int)X]
#define DECPARTSTR(X) [NSString stringWithFormat:#"%d",(int)(((float)X-(int)X)*100)]
- (NSString*)formatFloat:(float)f
{
NSString* result;
result = [NSString stringWithFormat:#"%.2f",f];
if ([DECPARTSTR(f) isEqualToString:#"0"]) return INTPARTSTR(f);
if ([INTPARTSTR(f) length]==5) return INTPARTSTR(f);
if ([result length]>5)
{
int diff = (int)[result length]-7;
NSString* newResult = #"";
for (int i=0; i<[result length]-diff-1; i++)
newResult = [newResult stringByAppendingFormat:#"%c",[result characterAtIndex:i]];
return newResult;
}
return result;
}
Testing it :
- (void)awakeFromNib
{
NSLog(#"%#",[self formatFloat:234.63]);
NSLog(#"%#",[self formatFloat:1234.65]);
NSLog(#"%#",[self formatFloat:11234.65]);
NSLog(#"%#",[self formatFloat:11234]);
}
Output :
2012-04-26 19:27:24.429 newProj[1798:903] 234.63
2012-04-26 19:27:24.432 newProj[1798:903] 1234.6
2012-04-26 19:27:24.432 newProj[1798:903] 11234
2012-04-26 19:27:24.432 newProj[1798:903] 11234
Here is how I implemented this in my code. I don't know how efficient it is, I hope not bad.
So I create a global NSNumberFormatter
NSNumberFormatter* numFormatter;
and initialize it somewhere:
numFormatter=[[NSNumberFormatter alloc]init];
Then I format number with the following function:
- (NSString*)formatFloat:(Float32)number withOptimalDigits:(UInt8)optimalDigits maxDecimals:(UInt8)maxDecimals
{
NSString* result;
UInt8 intDigits=(int)log10f(number)+1;
NSLog(#"Formatting %.5f with maxDig: %d maxDec: %d intLength: %d",number,optimalDigits,maxDecimals,intDigits);
numFormatter.maximumFractionDigits=maxDecimals;
if(intDigits>=optimalDigitis-maxDecimals) {
numFormatter.usesSignificantDigits=YES;
numFormatter.maximumSignificantDigits=(intDigits>optimalDigits)?intDigits:optimalDigits;
} else {
numFormatter.usesSignificantDigits=NO;
}
result = [numFormatter stringFromNumber:[NSNumber numberWithFloat:number]];
return result;
}
Is this a bug when using maximumFractionDigits and maximumSignificantDigits together on NSNumberForamtter on iOS 8?
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.maximumFractionDigits = 2;
formatter.maximumSignificantDigits = 3;
NSLog(#"%#", [formatter stringFromNumber:#(0.3333)]); // output 0.333 expected 0.33
It works fine if I only use maximumFractionDigits
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.maximumFractionDigits = 2;
NSLog(#"%#", [formatter stringFromNumber:#(0.3333)]); // output expected .33
NSNumberFormatter maximumFractionDigits and maximumSignificantDigits bug

How to round Decimal values in Objective C

This may be a easy question but i am not able to find the logic.
I am getting the values like this
12.010000
12.526000
12.000000
12.500000
If i get the value 12.010000 I have to display 12.01
If i get the value 12.526000 I have to display 12.526
If i get the value 12.000000 I have to display 12
If i get the value 12.500000 I have to display 12.5
Can any one help me out please
Thank You
Try this :
[NSString stringWithFormat:#"%g", 12.010000]
[NSString stringWithFormat:#"%g", 12.526000]
[NSString stringWithFormat:#"%g", 12.000000]
[NSString stringWithFormat:#"%g", 12.500000]
float roundedValue = 45.964;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:2];
[formatter setRoundingMode: NSNumberFormatterRoundUp];
NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:roundedValue]];
NSLog(numberString);
[formatter release];
Some modification you may need-
// You can specify that how many floating digit you want as below
[formatter setMaximumFractionDigits:4];//2];
// You can also round down by changing this line
[formatter setRoundingMode: NSNumberFormatterRoundDown];//NSNumberFormatterRoundUp];
Reference: A query on StackOverFlow
Obviously taskinoor's solution is the best, but you mentioned you couldn't find the logic to solve it... so here's the logic. You basically loop through the characters in reverse order looking for either a non-zero or period character, and then create a substring based on where you find either character.
-(NSString*)chopEndingZeros:(NSString*)string {
NSString* chopped = nil;
NSInteger i;
for (i=[string length]-1; i>=0; i--) {
NSString* a = [string substringWithRange:NSMakeRange(i, 1)];
if ([a isEqualToString:#"."]) {
chopped = [string substringToIndex:i];
break;
} else if (![a isEqualToString:#"0"]) {
chopped = [string substringToIndex:i+1];
break;
}
}
return chopped;
}