我想执行一些计算,我希望结果正确到一些小数位,比如12。 所以我写了一个样本:
#define PI 3.1415926535897932384626433832795028841971693993751
double d, k, h;
k = 999999/(2*PI);
h = 999999;
d = PI*k*k*h;
printf("%.12f\n", d);
但它给出了输出:
79577232813771760.000000000000
我甚至使用了setprecision(),但相同的答案却是指数形式。
cout<<setprecision(12)<<d<<endl;
打印
7.95772328138e+16
也使用了长双,但徒劳无功。
除了在long long int类型中分别存储整数部分和小数部分之外,还有其他方法吗?
如果是这样,可以做些什么来准确地得到答案?
答案 0 :(得分:6)
double只有大约16位精度的十进制数字。小数点后的所有内容都是无稽之谈。 (事实上,该点的最后一个数字或两个数字可能与无限精度计算不一致。)
长双不标准化,AFAIK。可能是在您的系统上它与double相同,或者不再精确。这会让我感到有些惊讶,但它并没有违反任何规定。
答案 1 :(得分:4)
您需要再次阅读Double-Precision个概念; 更仔细。
double
使用64位提高了精度
小数点之前的东西比之后的东西更重要。
因此,当你有一个大的整数部分时,它将截断较低的精度 - 这在这里以rounding off
的形式在各种答案中描述。
<强>更新强>:
为了提高精确度,您需要使用一些库或更改您的语言
检查另一个问题:Best coding language for dealing with large numbers (50000+ digits)
10000000000.123456789
之类的值,则
我对你正在研究的应用程序(天文学?)非常感兴趣。10000
之下,那么您应该没问题。 <强> UPDATE2 强>:
如果您必须证明特定公式在约束误差限制内准确工作的能力,那么可以采用的方法是修复公式的处理,以便引入最小的误差。
实施例,
(x * y) / z
max(x,y)/z * min(x,y)
(x * y)
之后可能溢出的原始形式,如果不符合double
的16位小数,则会失去精确度. 2-digit regular-precision
`42 * 7 290 297
(42 * 7)/2 290/2 294/2
Result ==> 145 147
But ==> 42/2 = 21
21 * 7 = 147
这可能是您竞赛的目的。
答案 2 :(得分:1)
大多数计算机使用的双精度二进制格式只能容纳大约16位数字,之后您将进行四舍五入。见http://en.wikipedia.org/wiki/Double-precision_floating-point_format
答案 3 :(得分:1)
浮点值具有数字限制范围。仅仅因为您的“PI”值的数字是double
的六倍,所以支持不会改变硬件的工作方式。
典型的(IEEE754)double
将产生大约15-16个小数位。无论是0.12345678901235,1234567.8901235,12345678901235或12345678901235000000000,还是其他一些变体。
换句话说,是的,如果你完全计算你的计算,你会得到很多小数位,因为pi
永远不会结束。在计算机上,无论您使用什么输入值,您都会获得大约15-16位数字 - 所有更改都是小数位所在的序列中的位置。要获得更多,您需要“大量支持”,例如Gnu Multiprcession(GMP)库。
答案 4 :(得分:0)
你正在寻找这告诉ostream 不是使用指数形式。std::fixed
。
cout << setprecision(12) << std::fixed << d << endl;