Tientuinë
Tientuinë

Reputation: 275

Boost variable precision numbers seem not to respect stream precision flag

Question: While migrating some code to Boost Multiprecision, from a home-brewed OOP-wrapper around MPFI, I noticed that printing a variable precision Boost number into an output stream apparently ignores the stream's precision parameter. In fact, the behavior for variable precision is the same as for precision of 20, regardless of the actual precision of the number. If this is the intended behavior instead of a bug, then I am curious if anyone can shed light on the rationale behind it.


Additional background: When using a fixed precision type such as mpfi_float_100, printing the interval shows all digits up to the specified stream precision. However, when using the variable precision type mpfi_float set to the same precision of 100, printing the interval shows a small fraction of the digits, seemingly ignoring the stream precision. Importantly, printing the lower/upper bounds directly shows all expected digits, exactly matching the output observed in the fixed precision case (except when precision is less than 20, since that seems to be the minimum precision for variable precision mpfi_float).

Here is a small sample program that highlights the observed behavior:

#include <boost/multiprecision/mpfi.hpp>
#include <iostream>

int main(int argc, char** argv)
{
    constexpr unsigned TESTPREC = 100;

    using namespace std;
    using namespace boost::multiprecision;
    cout.precision(5000);

    // Printing a fixed precision number always displays maximum digits when output
    number<mpfi_float_backend<TESTPREC>> a = 2;
    number<mpfi_float_backend<TESTPREC>> root_a = sqrt(a);
    cout << root_a << endl; // prints bounds at 332 and 334 digits, respectively
    cout << lower(root_a) << endl; // prints 332 digits for lower bound
    cout << upper(root_a) << endl; // prints 334 digits for upper bound
    cout << endl;

    // Printing a variable precision number may not display all digits when output
    mpfi_float b = 2;
    mpfi_float::default_precision(TESTPREC);
    mpfi_float root_b = sqrt(b);
    cout << root_b << endl; // prints bounds at just 68 and 67 digits, respectively
    cout << lower(root_b) << endl; // prints 332 digits for lower bound
    cout << upper(root_b) << endl; // prints 334 digits for upper bound
    cout << endl;

    return 0;
}

Here is a table summarizing the behavior I observed for several precision values:

Prec Type TESTPREC Lower digits Upper digits Sig. digits
Variable Any 68 67 19
Fixed 10 35 30 11
Fixed 20 68 67 19
Fixed 50 168 167 50
Fixed 100 332 334 101
Fixed 500 1663 1662 501
Fixed 1000 3324 3323 1001

My build environment:

Thanks to everyone who takes the time to read this.

Upvotes: 1

Views: 46

Answers (0)

Related Questions