我有关于循环中浮动值增量的查询。
我有以下代码
float add = 1.02f;
float counter = 0.0f;
for (int i = 0; i < 20; i++) {
counter += add;
NSLog(@"%f",counter);
}
执行此循环时,我得到以下结果
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
这是预期的结果
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
为什么我在循环中得到一些浮点而不添加它。
我需要循环超过1000次。我想要浮点变量中的值。
提前致谢。
答案 0 :(得分:6)
这是因为float
无法以精确的精度表示您拥有的值。有两种简单的方法可以解决这个问题:
1.02
变为102
,2.04
变为204
,等等上。NSDecimalNumber
代表您的数字 - 与float
不同,NSDecimalNumber
可以完全精确地表示您的所有值。以下是如何实施第一种方法:
int add = 102;
int counter = 0;
for (int i = 0; i < 20; i++) {
counter += add;
NSLog(@"%d.%d", counter/100, counter%100);
}
以下是如何实施第二种方法:
NSDecimalNumber add = [NSDecimalNumber decimalNumberWithString:@"1.02"];
NSDecimalNumber counter = [NSDecimalNumber zero];
for (int i = 0; i < 20; i++) {
counter = [counter decimalNumberByAdding:add];
NSLog(@"%@", counter);
}
答案 1 :(得分:3)
为什么我在循环中得到一些浮点而不添加它。
因为float
是二进制类型,不能完全表示十进制值。我没有试图完全正确地解释,而是让我指出一篇着名的论文What Every Computer Scientist Should Know About Floating Point Arithmetic。
答案 2 :(得分:0)
计算机中的浮点数表示是近似值,它们并不精确。有时您最终会尝试显示一个无法在计算机的浮点数实现中精确表示的数字,因此它会为您提供近似值。此外,浮点数的重复乘法,加法等也会产生小的算术误差。您可以做的最好的事情是使用double
s,其精度高于float
s。在特殊情况下,您还可以用不同的格式表示数据,只需更改向用户显示的方式即可满足他们的期望。例如,当使用美元和美分时,您可以将总数存储为分数(这只是一个整数),然后将其格式化为用户正确显示为美元和美分。当时没有浮动点四舍五入的问题。
答案 3 :(得分:0)
浮点数使用四个字节= 32位。
精度:通过 number_of_mantissa_bits * Log10(2)计算小数位数精度。因此,单精度和双精度分别为~7.2和~15.9。
这就是为什么你开始看到第7位的舍入错误