我只是开始学习C ++并且一直在搞乱浮点值和双值。下面是两个代码片段,在我看来,它们做同样的事情,但给出了不同的结果。我错过了什么?有人可以解释第一个代码必须具有的精度误差,以获得与第二个不同的结果。
int _tmain(int argc, _TCHAR* argv[])
{
const float f = 0.1;
const double d = 0.1;
int counter = 0;
for(counter; ((double)counter * f - (double)counter * d) < 0.34; counter++) {}
cout << "Iterations = " << counter << "\n" ;
system("pause");
return 0;
}
int main (int argc, const char * argv[])
{
float time_f = 0.1;
double time_d = 0.1;
float total_f = 0;
double total_d = 0;
int count=0;
double difference = 0;
while (true) {
total_d = count * time_d;
total_f = count * time_f;
if(total_f - total_d >= 0.34){
break;
}
count++;
}
std::cout << count << "\n";
system("pause");
}
我在float和double之间修改了for循环条件的强制转换,但值没有差别。
答案 0 :(得分:2)
float
和double
都有一个有限的表示,这意味着它们
采取一系列离散值,而不仅仅是任何真正的价值。在
特别是,在您的示例中,0.1
没有确切的浮点数
在我所知道的任何现代机器上的表示(所有这些都使用基础
在实现中它是2的幂 - 0.1
是1/5 *
1/2
,没有任何1/5
的倍数可以有限
表示除非基数是5的倍数。
结果是float
和double
具有相同的基础
表示(通常不是这种情况),或者会有差异
count
与0不同。
这个主题的通常参考是 “什么 每个计算机科学家都应该知道浮点数 算术”。直到你阅读和理解(或至少 理解其含义)它,你不应该触摸机器漂浮 点。
答案 1 :(得分:1)
这两个代码片段之间的区别在于强制转换。 counter * f
被转换为在第一个片段中加倍并在第二个片段中存储为浮点变量。
以下是它的外观示例:
#include <stdio.h>
int main(int argc, char* argv[])
{
const float f = 0.1;
const double d = 0.1;
int count = 0;
for(count; (double)(count * f) - (double)(count * d) < 0.34; count++);
printf("Iterations = %d\n", count);
count = 0;
while (true)
{
double total_d = count * d; // is equal to (double)(count * d)
double total_f = count * f; // is equal to (double)(count * f)
if (total_f - total_d >= 0.34)
break;
count++;
}
printf("Iterations = %d\n", count);
return 0;
}
答案 2 :(得分:0)
你还没有计算加倍数:
total_d = count * time_d;
total_f = count * time_f;
另一方面,这些循环永远不会结束,因为两个减法操作数具有相同的值:S