[英]C++ Strange error, “no conversion from 'int' to 'int (__cdecl *)(float,float)'”
[英]Strange conversion from float to int
for(float i = 40; i <= 42; i+=0.1f)
{
float offset = (i-40) * 10 * sizeof(float);
int wtf = offset;
printf("%.1f =?= %d\n", offset, wtf);
fseek(fin, offset, SEEK_SET);
fread(&tf, sizeof(float), 1, fin);
//printf("%.1f %.4f\n", i, tf);
}
输出:
0.0 =?= 0 4.0 =?= 3 8.0 =?= 7 12.0 =?= 11 16.0 =?= 15 20.0 =?= 19 24.0 =?= 23 28.0 =?= 27 32.0 =?= 31 36.0 =?= 35 40.0 =?= 39 44.0 =?= 43 48.0 =?= 47 52.0 =?= 51 56.0 =?= 55 60.0 =?= 59 64.0 =?= 63 68.0 =?= 67 72.0 =?= 71 76.0 =?= 75 80.0 =?= 79
我不明白这个,你能帮帮我吗?
问题是0.1
不能完全表示为二进制浮点数。 每个float
值都比您预期的要小一些,转换为int
向下舍入,给出比您预期的值小一的值。
您可以通过四舍五入到最接近的整数来获得预期值:
int wtf = std::round(offset);
当i = 40.1f
偏移量将是3.99993896
,它不完全是4.对于您的示例,如果使用c ++ 11标准或者如果舍入不可用,则可以使用std::round(offset)
std::floor(offset + 0.5f);
浮点不能代表宇宙中的所有值,并且在某些情况下,纸张上的数学在浮点上是正确的,它可能不是。
在碱2中表示的0.1是
0.0001100110011001100110011001100110011...
分数中的0011
无限重复,正如3
在1/3 = 0.3333333 ...基数10中所做的那样。由于实际浮点值只能保持有限数量的数字,因此近似中必然存在误差。
唯一可以用基数2中有限位数表示的小数是那些有理数,其分母是2的整数。例如,用0.125f(= 1/8)代替0.1f
for(float i = 40; i <= 42; i+=0.125f)
{
float offset = (i-40) * 10 * sizeof(float);
int wtf = offset;
printf("%.1f =?= %d\n", offset, wtf);
}
导致没有截断错误的值:
0.0 =?= 0
5.0 =?= 5
10.0 =?= 10
15.0 =?= 15
20.0 =?= 20
25.0 =?= 25
30.0 =?= 30
35.0 =?= 35
40.0 =?= 40
45.0 =?= 45
50.0 =?= 50
55.0 =?= 55
60.0 =?= 60
65.0 =?= 65
70.0 =?= 70
75.0 =?= 75
80.0 =?= 80
这是因为0.125
碱基10精确等于0.001
碱基2。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.