iPhone - Rounding a float does not work - objective-c

I can't achieve rounding a float.
Those calls all returns me 3.5999999 and not 3.6 for theoTimeoutTrick and theoTimeout.
How may I achieve to get that 3.6 value, into NSString AND float vars ?
#define minTimeout 1.0
#define defaultNbRetry 5
float secondsWaitedForAnswer = 20.0;
float minDelayBetween2Retry = 0.5;
int theoNbRetries = defaultNbRetry;
float theoTimeout = 0.0;
while (theoTimeout < minTimeout && theoNbRetries > 0) {
theoTimeout = (secondsWaitedForAnswer - (theoNbRetries-1)*minDelayBetween2Retry) / theoNbRetries;
theoNbRetries--;
}
float theoTimeoutTrick = [[NSString stringWithFormat:#"%.1f", theoTimeout] floatValue];
theoTimeout = roundf(theoTimeout * 10)/10.0;

From Rounding numbers in Objective-C:
float roundedValue = round(2.0f * number) / 2.0f;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:1];
[formatter setRoundingMode: NSNumberFormatterRoundDown];
NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:roundedValue]];
[formatter release];
That will get you a rounded string. You can parse it back into a float I'm sure.
Okay, here's some test code and some results:
NSLog(#"%f", round(10*3.56)/10.0);
=>3.600000
NSLog(#"%f", round(10*3.54)/10.0);
=>3.500000
NSLog(#"%f", round(10*3.14)/10.0);
=>3.100000
Okay, you know what? Your original code works as intended on my machine, OSX 10.6 and Xcode 4. How exactly are you seeing your output?

Related

Rounding float number upto two decimal places

I am trying to round a floating value upto two decimal places. I am using objective-c
e.g 1.47567 should be like this , 1.47 .. Please help
Thnx .
float num = 1.47567;
num *= 100;
if(num >= 0) num += 0.5; else num -= 0.5;
long round = num;
num = round;
num /= 100;
NSLog(#"%.2f",num);
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2];
NSString *formattedNumber = [formatter stringFromNumber:#(self.speed)];
double value = 1.47567;
double roundedValue = round(value * 100.0) / 100.0;
Of course you can use a named constant in place of 100.0. This is just a demo.
Do this
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2];
NSString *formattedNumber = [formatter stringFromNumber:#(self.speed)];
float numTwoDecimalDigits = atof([formattedNumber UTF8String]);
NSLog(#"%.2f", 1.47567);
would round to two decimal places. If you want to "cut", there are different options. For example:
NSLog(#"%.2f", floor(1.47567 * 100) / 100);

Rounded of a float with a decimal

Do someone know if there is a method in order to round a float two numbers after the comme.
Examples :
10.28000 -> 10.3
13.97000 -> 14.0
5.41000 -> 5.4
Thanks a lot !
Regards,
Sébastien ;)
Use NSNumberFormatter to create a string with the specified faction digits.
float num = 10.28000;
formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:1];
NSNumber *value = [NSNumber numberWithFloat:num];
NSString *newNumString = [formatter stringFromNumber:value];
Try this:
float aFloatValue = 3.1415926;
NSString *formatted = [NSString stringWithFormat:#"%01.1f", aFloatValue];
NSLog(#"Formatted: %#", formatted);
Think of it as a good old sprintf.
you could also try
float num = 10.28000
float result = (roundf(num * 10.0))/10.0;
(multiply by 10, then round, then divide by 10 again)
don't forget the .0 so that the division is by a float and not by an integer, which will round it again
The pure Cocoa way with NSRoundPlain behaviour:
- (NSDecimalNumber *)decimalNumberForFloat:(float)f_
{
NSNumber *number = [NSNumber numberWithFloat:f_];
NSDecimal decimal = [number decimalValue];
NSDecimalNumber *originalDecimalNumber = [NSDecimalNumber decimalNumberWithDecimal:decimal];
NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:0
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO];
return [originalDecimalNumber decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
}
since NSDecimalNumber is a subclass of NSNumber, to obtain the primitive float call -[NSDecimalNumber floatValue]
Try this out:
float myFloat = 10.4246f;
myFloat = ((int) ((myFloat * 100) + 5)) / 100.0f;
float fval = 1.54f;
float nfval = ceilf(fval * 10.0f + 0.5f)/10.0f;

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

Format number as percent

I have written this code and I want to format the number z as percent.
float l = ([textField2.text floatValue]);
float g = ([textField1.text floatValue]);
float x = l/1.23;
float y = x-g;
float z = y/l;
label.text = [[NSString alloc] initWithFormat:#"%2.2f \%",z];
Make your code as follows.
label.text = [[NSString alloc] initWithFormat:#"%2.2f %%",(z*100)];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterPercentStyle];
[numberFormatter setMinimumFractionDigits:2]; //optional
....
NSNumber *number = [NSNumber numberWithFloat:0.435];
NSLog(#"%#", [numberFormatter stringFromNumber:number] );
43,50 %
You need to use %% in order to print a percent sign in a format string.

Convert string to float in Objective-C

How do I convert a string to a float in Objective-C?
I am trying to multiply a couple of strings I am getting back from JSON:
float subTotal = [[[[purchaseOrderItemsJSON objectAtIndex:i] objectAtIndex:j] objectForKey:#"Price"] floatValue];
NSLog(#"%#", subTotal);
This gives me: (null) in the console. I know that there is a valid string coming out of that array because I am already using it to display its value in a label.
your_float = [your_string floatValue];
EDIT:
try this:
NSLog(#"float value is: %f", your_float);
The proper way of doing this is
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
float value = [numberFormatter numberFromString:#"32.12"].floatValue;