我有一个控制台应用程序,其功能可以划分Fibonacci系列的整数,演示任何Fibonacci系列中的比率如何接近Φ。我有用Go和C++11
编写的simliar代码。在Go
(或科学计算器)中,函数返回int64
的值,结果显示Ubuntu终端会话中最多16位数的精度,例如:
1.6180339937902115
在C ++ 11中,我使用cout
在结果中看不到更多5位数的精度。结果在如下函数中声明为long double
:
typedef unsigned long long int ULInt;
typedef std::vector< ULInt> ULIntV;
std::vector<long double > CalcSequenceRatio( const ULIntV& fib )
{
std::vector<long double> result;
for ( int i = 0; i != fib.size( ); i ++ )
{
if ( i == ( fib.size( ) - 1 ) )
{
result[i] = 0;
break;
}
long double n = fib[i + 1];
long double n2 = fib[i];
long double q = n / n2;
result.push_back( q );
}
return result;
}
虽然传递给fib
的向量CalcSequenceRatio( const ULIntV& fib )
包含超过100个条目,但在16个条目之后,结果集中的所有值都显示为
1.61803
除了Go(或在计算器中)之外,其余值都被舍入,我可以看到实际值被扩展到至少16位精度。
如何让CalcSequenceRatio()
返回更准确的值?是否有问题,因为从long long int
到long double
是一个沮丧的人?我需要将fib系列作为vector<long double>
传递吗?怎么了?
修改
这个问题已被标记为重复,但这不是真的正确,因为这个问题并不直接涉及cout
:尽管分析证明了其他因素可能会产生影响cout
是问题所在。我发布了正确的答案:
问题在于cout,这是解决方案......正如在中所解释的那样 另一个问题......
答案 0 :(得分:3)
听起来您希望使用std::numeric_limits<T>::max_digits10
进行不同的“往返”转换 - 与std::setprecision
结合使用。
float
,这通常是(9)
=&gt;或1.8
格式。 double
通常为(17)
=&gt; 1.16
long double
通常在x86或128位extended precision类型上实现为80位quad precision类型,(21)
=&gt; 1.20
和(36)
=&gt; 1.35
分别格式化。但是,long double
只需要提供至少与double
一样多的精度。
关于相关主题here有一系列很好的笔记。
答案 1 :(得分:0)
问题在于std::cout
。
我使用std::setprecision(50)
修正了它,如How do I print a double value with full precision using cout?中所述,这显示了我这样的价值观:
<强> 1.6180339887498948482072100296669248109537875279784 强>
为了使其灵活,我给了用户输入所需精度的选项:
void printGolden( const std::vector<long double>& golden )
{
cout << "Enter desired precision:" << endl;
int precision{};
cin >> precision;
std::cout << std::setprecision( precision );
for ( auto i : golden )
{
std::cout << i << "; ";
}
}