2015-11-27 37 views
1

我有一个看起来很简单的C++问题,困扰着我。代码在C++中乘双倍错误

#include <iostream> 
using namespace std; 

int main() { 
    // your code goes here 
    double c = 9.43827 * 0.105952 ; 
    cout << c << endl ; 
    return 0; 
} 

的输出为1只是1。我想这是因为失去精度基于双打如何存储在C++中,但肯定必须有在C++中获得某种精确的方式( 2或3位小数)。

回答

-1

尝试使用cout<<setprecision(12)<<c<<endl;

setprecision设置小数精度被用来在输出操作格式化浮点值。

source

+0

冰:9.43827 * 0.105952 = 1.00000358304,setprecision(12)= 1.00000358305 – msmith81886

+0

由于@Max疼痛。我真正需要做的是将这个双重乘法的结果传递给另一个双重乘法。使用cout只是为了说明问题。我如何将更高精度的结果传递给另一个double? – reayn3

+1

@ reayn3:它已经完全精确*存储*。 –

1

这不是在存储精度损失,它的精度损失转换为文本。双插槽默认为六位有效数字。此处的产品1.000003583取整为六位有效数字,为1.00000。另外,如果你没有设置showpoint,尾随零和小数点将被抑制,所以你会看到一个空的1.要显示小数点,使用std::cout << std::showpoint << c << '\n';。要查看更多有效数字,请使用std::cout << std::setprecision(whatever) << c << '\n';,其中whatever是您希望格式化程序使用的位数。

+0

太棒了!谢谢你的澄清@PeteBecker。也就是说,这是一个很好的展示不同的编程语言如何有趣的细微差别。谁会想到截断到只有6位有效数字。为什么不是编译器可以提供的10或11或者更高的准确度......然后程序员可以删除她不需要的东西。 – reayn3

+1

@ reayn3 - 最简单的答案是C就是这么做的。

+0

哈哈。我猜如此@PeteBecker。无论如何 – reayn3

0
#include <stdio.h> 

int main() { 
    // your code goes here                    
    double c = ((double)9.43827) * 0.105952 ; 
    for(int i = (sizeof(double)*8)-1; i >= 0; i--) { 
    printf("%ld", (*(long*)&c>>i)&1); 
    } 
} 

如果你运行这个,你可以清楚地看到你的double的位表示不是整数值1.你不会丢失任何数据。

0011111111110000000000000000001111000001110100001010001001001001

但它是非常接近1,所以这就是被打印出来。

+0

真棒。感谢@xaxxon的位级解释。很高兴我不丢失任何数据:) – reayn3