当 double 转换为 int 时,最后一位数字丢失
The last digit is lost when the double is cast to int
考虑以下程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int i;
long int rr;
double dd;
double arr[10] = {55.550,55.551,55.552,55.553,55.554,55.555,55.556,55.557,55.558,55.559};
printf("\n\nTest1");
for(i=0;i<10;i++)
{
dd = 100 * arr[i];
rr = (long int)dd;
printf("\n 100 * %10.4lf == %10.4lf >>>>> %ld",arr[i], dd, rr);
}
printf("\n\nTest2");
for(i=0;i<10;i++)
{
printf("\n 100 * %10.4lf == %10.4lf >>>>> %ld",
arr[i], 100 * arr[i], (long int)(100 * arr[i]));
}
return 0;
}
在我执行这个东西后我得到:
Test1
100 * 55.5500 == 5555.0000 >>>>> 5555
100 * 55.5510 == 5555.1000 >>>>> 5555
100 * 55.5520 == 5555.2000 >>>>> 5555
100 * 55.5530 == 5555.3000 >>>>> 5555
100 * 55.5540 == 5555.4000 >>>>> 5555
100 * 55.5550 == 5555.5000 >>>>> 5555
100 * 55.5560 == 5555.6000 >>>>> 5555
100 * 55.5570 == 5555.7000 >>>>> 5555
100 * 55.5580 == 5555.8000 >>>>> 5555
100 * 55.5590 == 5555.9000 >>>>> 5555
Test2
100 * 55.5500 == 5555.0000 >>>>> 5554 <-- Look at here !
100 * 55.5510 == 5555.1000 >>>>> 5555
100 * 55.5520 == 5555.2000 >>>>> 5555
100 * 55.5530 == 5555.3000 >>>>> 5555
100 * 55.5540 == 5555.4000 >>>>> 5555
100 * 55.5550 == 5555.5000 >>>>> 5555
100 * 55.5560 == 5555.6000 >>>>> 5555
100 * 55.5570 == 5555.7000 >>>>> 5555
100 * 55.5580 == 5555.8000 >>>>> 5555
100 * 55.5590 == 5555.9000 >>>>> 5555
Process returned 0 (0x0) execution time : -0.000 s
Press any key to continue.
好像当你像这样相乘然后投射 55.550 时,最后一位数字被遗漏了。这正常吗?
在那种情况下应该如何进行转换?
标准的float精度问题。 55.550 的值不能准确地存储在内存中,因此存储了一些不同但非常接近的值。因此,不同的操作顺序(甚至包括将中间结果存储到 double
中)都会影响结果。很可能在第一次测试中,dd
中的值变为 5555,而在第二种情况下 100 * arr[i]
变为 5554.9999999997.
考虑以下程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int i;
long int rr;
double dd;
double arr[10] = {55.550,55.551,55.552,55.553,55.554,55.555,55.556,55.557,55.558,55.559};
printf("\n\nTest1");
for(i=0;i<10;i++)
{
dd = 100 * arr[i];
rr = (long int)dd;
printf("\n 100 * %10.4lf == %10.4lf >>>>> %ld",arr[i], dd, rr);
}
printf("\n\nTest2");
for(i=0;i<10;i++)
{
printf("\n 100 * %10.4lf == %10.4lf >>>>> %ld",
arr[i], 100 * arr[i], (long int)(100 * arr[i]));
}
return 0;
}
在我执行这个东西后我得到:
Test1
100 * 55.5500 == 5555.0000 >>>>> 5555
100 * 55.5510 == 5555.1000 >>>>> 5555
100 * 55.5520 == 5555.2000 >>>>> 5555
100 * 55.5530 == 5555.3000 >>>>> 5555
100 * 55.5540 == 5555.4000 >>>>> 5555
100 * 55.5550 == 5555.5000 >>>>> 5555
100 * 55.5560 == 5555.6000 >>>>> 5555
100 * 55.5570 == 5555.7000 >>>>> 5555
100 * 55.5580 == 5555.8000 >>>>> 5555
100 * 55.5590 == 5555.9000 >>>>> 5555
Test2
100 * 55.5500 == 5555.0000 >>>>> 5554 <-- Look at here !
100 * 55.5510 == 5555.1000 >>>>> 5555
100 * 55.5520 == 5555.2000 >>>>> 5555
100 * 55.5530 == 5555.3000 >>>>> 5555
100 * 55.5540 == 5555.4000 >>>>> 5555
100 * 55.5550 == 5555.5000 >>>>> 5555
100 * 55.5560 == 5555.6000 >>>>> 5555
100 * 55.5570 == 5555.7000 >>>>> 5555
100 * 55.5580 == 5555.8000 >>>>> 5555
100 * 55.5590 == 5555.9000 >>>>> 5555
Process returned 0 (0x0) execution time : -0.000 s
Press any key to continue.
好像当你像这样相乘然后投射 55.550 时,最后一位数字被遗漏了。这正常吗?
在那种情况下应该如何进行转换?
标准的float精度问题。 55.550 的值不能准确地存储在内存中,因此存储了一些不同但非常接近的值。因此,不同的操作顺序(甚至包括将中间结果存储到 double
中)都会影响结果。很可能在第一次测试中,dd
中的值变为 5555,而在第二种情况下 100 * arr[i]
变为 5554.9999999997.