Reputation: 123
I have a query regarding floating value increment in loop.
I have following code
float add = 1.02f;
float counter = 0.0f;
for (int i = 0; i < 20; i++) {
counter += add;
NSLog(@"%f",counter);
}
While executing this loop I am getting following result
1.020000
2.040000
3.060000
4.080000
5.100000
6.120000
7.140000
8.160000
9.180000
10.200001
11.220001
12.240002
13.260002
14.280003
15.300003
16.320004
17.340004
18.360004
19.380005
20.400005
Here is expected result
1.020000
2.040000
3.060000
4.080000
5.100000
6.120000
7.140000
8.160000
9.180000
10.200000
11.220000
12.240000
13.260000
14.280000
15.300000
16.320000
17.340000
18.360000
19.380000
20.400000
Why i am getting some floating point in loop without adding it.
I need to loop more then 1000 times. And I want the value in float variable.
Thanks in advance.
Upvotes: 0
Views: 1433
Reputation: 8180
Floating point numbers use four bytes = 32 bits.
Precision: The number of decimal digits precision is calculated via number_of_mantissa_bits * Log10(2). Thus ~7.2 and ~15.9 for single and double precision respectively.
That's why you start to see rounding errors on the 7th digit
Upvotes: 0
Reputation: 8200
Floating point number representations in computers are approximations, they are not exact. Sometimes you end up trying to display a number that can't be exactly represented in the computer's floating point number implementation, so it gives you an approximation. Also you get small arithmetic errors from repeated multiplications, additions, etc. of floating point numbers. The best you can do is to use double
s, which have more precision than float
s do. In special circumstances, you could also represent your data in a different format and just change how you display it to the user to fit what they expect. For example, when working with dollars and cents, you could just store a total as a number of cents (which would be only an integer) and then format it to be shown as dollars and cents correctly for the user. There's no floating point rounding issues happening then.
Upvotes: 0
Reputation: 727087
This happens because float
cannot represent the values that you have with exact precision. There are two simple ways of fixing this:
1.02
becomes 102
, 2.04
becomes 204
, and so on.NSDecimalNumber
to represent your numbers - Unlike float
, NSDecimalNumber
can represent all your values with full precision.Here is how to implement the first approach:
int add = 102;
int counter = 0;
for (int i = 0; i < 20; i++) {
counter += add;
NSLog(@"%d.%d", counter/100, counter%100);
}
Here is how to implement the second approach:
NSDecimalNumber add = [NSDecimalNumber decimalNumberWithString:@"1.02"];
NSDecimalNumber counter = [NSDecimalNumber zero];
for (int i = 0; i < 20; i++) {
counter = [counter decimalNumberByAdding:add];
NSLog(@"%@", counter);
}
Upvotes: 6
Reputation: 125037
Why i am getting some floating point in loop without adding it.
Because float
is a binary type that doesn't represent decimal values exactly. Rather than trying to explain completely and correctly, let me point you to the well-known paper What Every Computer Scientist Should Know About Floating Point Arithmetic.
Upvotes: 3