实际上我的双重铸造不是解决方案。
#include <stdio.h>
int main(int argc, char **argv) {
int d_freq, d_freq_test;
double freq_mhz = 2110.0;
double step = 0.1;
while (freq_mhz < 2111.0) {
d_freq = (int)(freq_mhz * 20.0);
d_freq_test = (int)(float)(freq_mhz * 20.0);
printf("freq: %.1f, d_freq: 0x%04X, d_freq_test: 0x%04X\n", freq_mhz, d_freq, d_freq_test);
freq_mhz += step;
}
return 0;
}
这产生(错误):
freq: 2110.0, d_freq: 0xA4D8, d_freq_test: 0xA4D8
freq: 2110.1, d_freq: 0xA4DA, d_freq_test: 0xA4DA
freq: 2110.2, d_freq: 0xA4DC, d_freq_test: 0xA4DC
freq: 2110.3, d_freq: 0xA4DD, d_freq_test: 0xA4DD <-- :(
freq: 2110.4, d_freq: 0xA4DF, d_freq_test: 0xA4DF
freq: 2110.5, d_freq: 0xA4E1, d_freq_test: 0xA4E1
freq: 2110.6, d_freq: 0xA4E3, d_freq_test: 0xA4E3
freq: 2110.7, d_freq: 0xA4E5, d_freq_test: 0xA4E5
freq: 2110.8, d_freq: 0xA4E7, d_freq_test: 0xA4E7
freq: 2110.9, d_freq: 0xA4E9, d_freq_test: 0xA4E9
freq: 2111.0, d_freq: 0xA4EB, d_freq_test: 0xA4EB
虽然这段代码:
#include <stdio.h>
int main(int argc, char **argv) {
int d_freq, d_freq_test;
double freq_mhz = 2110.0;
double step = 0.1;
while (freq_mhz < 2111.0) {
d_freq = (int)(freq_mhz * 20.0);
d_freq_test = (int)(float)(freq_mhz * 20.0 + 0.5);
printf("freq: %.1f, d_freq: 0x%04X, d_freq_test: 0x%04X\n", freq_mhz, d_freq, d_freq_test);
freq_mhz += step;
}
return 0;
}
产生:
freq: 2110.0, d_freq: 0xA4D8, d_freq_test: 0xA4D8
freq: 2110.1, d_freq: 0xA4DA, d_freq_test: 0xA4DA
freq: 2110.2, d_freq: 0xA4DC, d_freq_test: 0xA4DC
freq: 2110.3, d_freq: 0xA4DD, d_freq_test: 0xA4DE <-- :)
freq: 2110.4, d_freq: 0xA4DF, d_freq_test: 0xA4E0
freq: 2110.5, d_freq: 0xA4E1, d_freq_test: 0xA4E2
freq: 2110.6, d_freq: 0xA4E3, d_freq_test: 0xA4E4
freq: 2110.7, d_freq: 0xA4E5, d_freq_test: 0xA4E6
freq: 2110.8, d_freq: 0xA4E7, d_freq_test: 0xA4E8
freq: 2110.9, d_freq: 0xA4E9, d_freq_test: 0xA4EA
freq: 2111.0, d_freq: 0xA4EB, d_freq_test: 0xA4EC
哪个是对的。
所以这确实是舍入问题,一个精度问题,通过在 x20 乘法的结果上加上 0.5 来解决。