how to set precision in Objective-C - objective-c

In C++, there is a std::setprecision function can set float/double precision.
how can i set precision in Objective-C? and this print below:
(lldb) p 10/200
(int) $0 = 0
(lldb) p (float)10/200
(float) $1 = 0.0500000007
line 3 result is 0.0500000007, why is '7' in the result? how can i get the result is 0.05?

Floating-point numbers are binary floating-point numbers. 0.05 cannot be represented exactly by a binary floating point number. The result cannot ever be exactly 0.05.
In addition, you are quite pointlessly using float instead of double. float has only six or seven digits precision. Unless you have a very good reason that you can explain, use double, which gives you about 15 digits of precision. You still won't be able to get 0.05 exactly, but the error will be much less.

You may use NSNumberFormatter to format objects in a wide variety of ways --- too numerous to list here, see the documentation available from Xcode. Also see the Data Formatting Guide.

You must make change between % modulo operator and its identifier f in order to get desired result.
NSString* formattedNumber = [NSString stringWithFormat:#"%.02f", myFloat];
%.02f tells the formatter that you will be formatting a float (%f) and, that should be rounded to two places, and should be padded with 0s.
Example:
%f = 25.000000 // results 25.000000
%.f = 25 // results 25
%.02f = 25.00 // results 25.00

plz use
double A = 0.0500000007;
NSString *b =[NSString stringWithFormat:#"$%.02f",A] ;
double B = [b doubleValue];

Related

Rounding issue when using NSString and %f [duplicate]

I have a floating point number that have more decimal digits, for example:
float fRes = 10.0 / 3.0;
actually the fRes value is 3.3333333333333
it's possible set for example 2 decimal digits:
float fRes = 10.0 / 3.0;
// fRes is 3.333333333333333333333333
float fResOk = FuncRound( fRes, 2 );
// fResOk is 3.33
thanks in advance
I don't know where you are using this rounded number, but you should only round your value when displaying it to the user, there are C based format string ways to round floating point numbers for example
[NSString stringWithFormat:#"%.2f", value];
as you may have already read, floating point number are approximations of real numbers, so doing fResOk = roundf( fRes*100.0)/100.0; may not give you 3.33 but a number which is just as close as you can get with floating point number to 3.33.
Assuming that you're looking for the correct function to round to a certain number of digits, you'll probably find it easiest to do the following:
fResOk = roundf( fRes*100.0)/100.0;
That will multiply the value by 100 (giving you your 2 digits of significance), round the value, and then reduce it back to the magnitude you originally started with.

Objective-C - How to increase the precision of a float number

Can someone please show me the way to set the precision of a float number to desired length. Say I have a number 2504.6. As you see the precision here is only 1. I want to set it to six.I need this because I compare this value with the value obtained from
[txtInput.text floatValue]. And even if I enter 2504.6 to the text box it will add 5 more precisions and will be 2504.600098. And when I compare these two values they appear to be not equal.
Floats are approximates. The way floats are stored does not allow for arbitrary precision. Floats (and doubles) are designed to store very large (or small) values, but not precise values.
If you need a very precise non-integer number, use an int (or long) and scale it. You could even write your own object class to handle that.
They won't appear to be equal
Btw this question has been asked before
Comparing float and double data types in objective C
Objective-C Float / Double precision
Make a float only show two decimal places
You can compare the numbers using NSDecimalNumber:
NSDecimalNumber *number = [NSDecimalNumber numberWithFloat:2504.6f];
NSDecimalNumber *input = [NSDecimalNumber decimalNumberWithString:txtInput.text];
NSComparisonResult result = [number compare:input];
if (result == NSOrderedAscending) {
// number < input
} else if (result == NSOrderedDescending) {
// number > input
} else {
// number == input
}
Comparing two float variables A and B using 'equal' operator is not very good idea, cause float numbers have limited precision. The best way to compare floats is
fabs(A - B) < eps
where eps is some very small value, say 0.0001
If you're operating with strings that represent the float values you can just compare strings and not the numbers.

In objective c from a float number I want to sepatate the decimals to do further math work on

I am setting up a calculator that will generate a float number after the user's input. As an example: if the answer generated is 1.75 that would actually represents 1.75 hours. I want to split the answer into two parts to read 1 hr. 45 min which will be more user friendly than .75 of an hour is.
So I need to be able to delete the whole digit(s) (in this example the "1") before the decimal to get a variable value using the .75 --kind of like this:
mIn = (.75 * 60) which would give me the 45 minutes value to put in my...
[NSString stringWithFormat:#"#% hr. #% min", hRs, mIn]; type of statement
Any help on this would be greatly appreciated.
You almost certainly do not want to use a float to store a user-entered number, particularly for a calculator. This will lead to decimal/binary rounding errors that will drive you crazy. You want to use NSDecimalNumber for this kind of work.
The other answers here will work, but you want to replace floor() with decimalNumberByRoundingAccordingToBehavior:. You'll use an NSDecimalNumberHandler with a rounding mode of NSRoundDown and an appropriate scale (probably 2 or 3 for your purposes).
Use floor(floatValue) to get the integer portion, subtract that from the floatValue to get the decimal portion.
Ex:
float floatValue = 1.75;
float integerPortion = floor(floatValue);
float decimalPortion = floatValue - integerPortion;
NSString *timeString = [NSString stringWithFormat:#"%.0f hr. %.0f min", integerPortion, decimalPortion * 60];
NSLog(#"timeString: %#", timeString);
NSLog output:
timeString: 1 hr. 45 min
You can cast the floating value to an int and subtract that from the value or you can floor it.
float time = 1.75;
int minutes = (time - (int)time) * 60; //or (time - floor(time)) * 60;
NSLog(#"Time: %#", [NSString stringWithFormat:#"%d hr. %d min", (int)time, minutes]);

iOS round a float

I have a floating point number that have more decimal digits, for example:
float fRes = 10.0 / 3.0;
actually the fRes value is 3.3333333333333
it's possible set for example 2 decimal digits:
float fRes = 10.0 / 3.0;
// fRes is 3.333333333333333333333333
float fResOk = FuncRound( fRes, 2 );
// fResOk is 3.33
thanks in advance
I don't know where you are using this rounded number, but you should only round your value when displaying it to the user, there are C based format string ways to round floating point numbers for example
[NSString stringWithFormat:#"%.2f", value];
as you may have already read, floating point number are approximations of real numbers, so doing fResOk = roundf( fRes*100.0)/100.0; may not give you 3.33 but a number which is just as close as you can get with floating point number to 3.33.
Assuming that you're looking for the correct function to round to a certain number of digits, you'll probably find it easiest to do the following:
fResOk = roundf( fRes*100.0)/100.0;
That will multiply the value by 100 (giving you your 2 digits of significance), round the value, and then reduce it back to the magnitude you originally started with.

NSTimeInterval to readable NSNumber

NSTimeInterval == double; (e.g. 169.12345666663)
How can I round up this double so that there are only 2 digits left after the "dot"?
It would be very good if the result is a NSNumber.
If this is for display purposes, take a look at NSNumberFormatter.
If you really want to round the double in your calculations for some reason, you can use the standard C round() function.
A NSDecimal can be rounded to a specified number of digits with NSDecimalRound().
double d = [[NSDate date] timeIntervalSince1970];
NSDecimal in = [[NSNumber numberWithDouble:d] decimalValue];
NSDecimal out;
NSDecimalRound( &out, &in, 2, NSRoundUp );
NSDecimalNumber *result = [NSDecimalNumber decimalNumberWithDecimal:out];
If you really want two digits left after the dot, multiply by 100, round it using round() function, divide it by 100 again. However, this will not guarantee that it really has only two digits after the dot, since by dividing it again, you may get a number that cannot really be expressed with floating point notation and when you expect 0.1 you may in fact get 0.09999..., that's because you cannot really express 0.1 using floating point notation.
If you just want to round it to two digits after the dot for display purposes, you can use NSNumberFormatter as has been suggested or just use:
printf("%.2f\n", yourTimeInterval);
NSLog(#"%.2f\n", yourTimeInterval);
or to get an NSString, you can also use the following, which is probably even faster than using a NumberFormatter (however, it won't be localized according to the user prefs):
NSString * intervalStr = nil;
char * intervalStrTmp = NULL;
asprintf(&intervalStrTmp, "%.2f", yourTimeInteval);
if (intervalStrTmp) {
intervalStr = [[NSString alloc] initWithUTF8String:intervalStrTmp];
free(intervalStrTmp);
}
In the vast majority of cases rounding a number is something you should only do at display time. The properties of floating-point numbers (double or not) make it impossible to store certain numbers at a fixed-precision.
For information about formatting a number so it displays to two decimal places, see this other post.
Does this HumanReadableTimeInterval help? It returns a NSString, though.
Alternatively, you can round yourself by multiplying with 100, converting to an integer and dividing through 100 again.
I would just use the ANSI C round() function.
You can always round the number using:
double round2dec(double a) { return round(a * 100) / 100; }
But chances are that the representation of the result as a double will not have only 2 decimals.
Now, if by using the == sign, you meant that the comparison of your two double numbers is made only to the second decimal. Here is what you can do:
fabs(round2dec(NSTimeInterval) - round2dec(double)) < std::numeric_limits<double>::epsilon()