How to round Decimal values in Objective C - 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;
}

Related

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:#"/"];
}

Manipulate string in objective-c to remove substring between 2 characters

I want to parse a date string that I receive from a web service. However, I sometimes receive the date with decimal component and sometimes without decimal component. Also, sometimes the date comes with a different number of decimal digits.
Assume you got the following date:
NSString *dateString = #"2013-07-22T220713.9911317-0400";
How can remove the decimal values? I want to end up with:
#"2013-07-22T220713-0400";
So I can process it with the DateFormatter that uses no decimal.
You could use a regular expression to match the first occurrence of a decimal followed by numbers, and remove them:
NSString *dateString = #"2013-07-22T220713.9911317-0400";
NSRegularExpression * regExp = [NSRegularExpression regularExpressionWithPattern:#"\\.[0-9]*" options:kNilOptions error:nil];
dateString = [dateString stringByReplacingCharactersInRange:[regExp rangeOfFirstMatchInString:dateString options:kNilOptions range:(NSRange){0, dateString.length}] withString:#""];
Based on #JeffCompton 's suggestion I ended up doing this:
+ (NSDate *)dateFromISO8601:(NSString *)dateString {
if (!dateString) return nil;
if ([dateString hasSuffix:#"Z"]) {
dateString = [[dateString substringToIndex:(dateString.length - 1)] stringByAppendingString:#"-0000"];
}
NSString *cleanDateString = dateString;
NSArray *dateComponents = [dateString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"."]];
if ([dateComponents count] > 1){
NSArray *timezoneComponents = [[dateComponents objectAtIndex:1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"-"]];
if ([timezoneComponents count] > 1){
cleanDateString = [NSString stringWithFormat:#"%#-%#", [dateComponents objectAtIndex:0], [timezoneComponents objectAtIndex:1]];
}
}
dateString = [cleanDateString stringByReplacingOccurrencesOfString:#":" withString:#""];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-d'T'HHmmssZZZ";
NSDate *resultDate = [dateFormatter dateFromString:dateString];
return resultDate;
}
This is a modification of some open-source code but I lost the reference to the original code.
The reason for all the modifications is that I am connecting to API's that can give me the date with decimals or without, and sometimes without the : separating HH, mm, and ss.

How can i display the number in such a format?

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.

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

Truncate extra zeroes when formatting a float into an NSString

I am trying to format some floats as follows:
1.1500 would be displayed as “$ 1.15”
1.1000 would be displayed as “$ 1.10”
1.0000 would be displayed as “$ 1.00”
1.4710 would be displayed as “$ 1.471”
1.4711 would be displayed as “$ 1.4711”
I tried with
NSString *answer = [NSString stringWithFormat:#"$ %.2f",myvalue];
This is exactly what NSNumberFormatters are for:
float onefifteen = 1.1500; // displayed as “$ 1.15”
float oneten = 1.1000; // displayed as “$ 1.10”
float one = 1.0000; // displayed as “$ 1.00”
float onefortyseventen = 1.4710; // displayed as “$ 1.471”
float onefortyseveneleven = 1.4711; // displayed as “$ 1.4711”
NSNumberFormatter * formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setUsesSignificantDigits:YES];
// The whole number counts as the first "significant digit"
[formatter setMinimumSignificantDigits:3];
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:onefifteen]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:oneten]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:one]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:onefortyseventen]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:onefortyseveneleven]]);
2011-12-15 19:36:52.185 SignificantCents[49282:903] $1.15
2011-12-15 19:36:52.190 SignificantCents[49282:903] $1.10
2011-12-15 19:36:52.190 SignificantCents[49282:903] $1.00
2011-12-15 19:36:52.191 SignificantCents[49282:903] $1.471
2011-12-15 19:36:52.192 SignificantCents[49282:903] $1.4711
try this :
NSString *answer = [NSString stringWithFormat:#"%.02f", myvalue];
I have figure out this. you can do this as per below implementation.
Please take a look at below demo code...
NSArray * numbers = [[NSArray alloc] initWithObjects:#"1.1500",#"1.1000",#"1.0000",#"1.4710",#"1.4711",nil];
for (int i=0; i<[numbers count]; i++) {
NSArray * floatingPoint = [[numbers objectAtIndex:i] componentsSeparatedByString:#"."];
NSString * lastObject = [[floatingPoint lastObject] stringByReplacingOccurrencesOfString:#"0" withString:#""];
if ([lastObject length] < 2) {
NSLog(#"%#",[NSString stringWithFormat:#"$ %.2f",[[numbers objectAtIndex:i] floatValue]]);
} else {
NSLog(#"%#",[NSString stringWithFormat:#"$ %g",[[numbers objectAtIndex:i] floatValue]]);
}
}
Thanks,
MinuMaster
Read the docs on format specifiers.