Domanda

I have a console app with a function that divides integers of a Fibonacci series, demonstrating how the ratio in any Fibonacci series approaches Φ . I have simliar code written in Go and inC++11. InGo (or a scientific calculator), the function returns values of int64 and the results show a precision of up to 16 digits in an Ubuntu Terminal Session, for example:

1.6180339937902115

In C++11 I can never see more that 5 digits of precision in the results usingcout. The results are declared aslong double in a function like this:

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;
 }

Although the vectorfib passed into CalcSequenceRatio( const ULIntV& fib ) contains over 100 entries, after 16 entries, all values in the result set are displayed as

1.61803

The rest of the value is being rounded although in Go (or in a calculator), I can see that the actual values are extended to at least 16 digits of precision.

How can I make CalcSequenceRatio() return more precise values? Is there is problem because going from long long int to long double is a downcast? Do I need to pass the fib series as vector<long double>? What's wrong?

Edit:

This question has been marked a duplicate, but this is not really correct, because the question does not deal directly with cout: There are other factors that might have made a difference, although the analysis proves that cout is the problem. I posted the correct answer:

The problem is with cout, and here is the solution... as explained in the other question...

È stato utile?

Soluzione 2

The problem here is withstd::cout.

I fixed it using std::setprecision(50), as explained in How do I print a double value with full precision using cout? That shows me values like this:

1.6180339887498948482072100296669248109537875279784

To make it flexible, I gave the user the option to enter the desired level of precision:

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

}

Altri suggerimenti

It sounds like you want to use: std::numeric_limits<T>::max_digits10 for distinct, 'round-trip' conversions - in conjunction with std::setprecision.

e.g., for float this is typically (9) => or 1.8 format. double is typically (17) => 1.16

A long double is typically implemented as an 80 bit extended precision type on x86, or a 128 bit quad precision type, with (21) => 1.20 and (36) => 1.35 formats respectively. However the long double is only required to provide at least as much precision as a double.

There's a good series of notes on related subjects here.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top