为什么在显示vector <long double =“”>?</long>时,我看不到所有有效数字

时间:2014-04-20 18:37:05

标签: c++ math c++11 floating-point-precision

我有一个控制台应用程序,其功能可以划分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 intlong double是一个沮丧的人?我需要将fib系列作为vector<long double>传递吗?怎么了?

修改

这个问题已被标记为重复,但这不是真的正确,因为这个问题并不直接涉及cout:尽管分析证明了其他因素可能会产生影响cout是问题所在。我发布了正确的答案:

  

问题在于cout,这是解决方案......正如在中所解释的那样   另一个问题......

2 个答案:

答案 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 << "; ";
    }

}