I wanted to have an std::complex<mpf_class> with a specific precision (400), and read in the complex from std::cin. I didn't know how to set the precision in the declaration of the complex, so I tried this first:
std::complex<mpf_class > c;
c.real().set_prec(400);
c.imag().set_prec(400);
std::cin >> c;
std::cout << std::setprecision(400) << c;
But with the input (0.12345678123456781234567812345678,0), I got the output (0.123456781234567812346,0). This isn't right because 400 bits of precision should be able to hold all the digits of the input. I wanted to make sure that std::complex could hold higher precision variables so I tried this:
mpf_class a(0, 400);
mpf_class b(0, 400);
std::cin >> a >> b;
std::complex<mpf_class> c(a, b);
std::cout << std::setprecision(400) << c;
With the same input, 0.12345678123456781234567812345678 0, the output was (0.12345678123456781234567812345678,0). So it held all the digits, but I had to both declare and read the complex parts first; not ideal.
But I was still trying to figure out what was causing the first code segment to not work. One difference I noticed between the first two code segments was that the precision in the first was set after the declaration of the mpf_class, while the second segment sets the precision during the mpf_class declaration. I just wanted to check that you could update the precision of an mpf_class so I tried this:
mpf_class a(0, 32);
a.set_prec(400);
std::cin >> a;
std::cout << std::setprecision(400) << a;
With the input 0.12354678123456781234567812345678, the output was the same which means the precision can be updated.
Finally I thought there might be some issue with the complex stream extraction operator and high precision decimals. So I set the precision of the mpf_class before declaring the complex, then declared the complex, then read in the complex:
mpf_class a, b;
a.set_prec(400);
b.set_prec(400);
std::complex<mpf_class> c(a, b);
std::cin >> c;
std::cout << std::setprecision(400) << c;
But with this the weirdest thing happened. With input (0.12345678123456781234567812345678,0) the output was (0.1234567812345678123456781234567799999999999999999999999999273060010609330153935727917471428455421640301869890510557285753902098601227437,0)
TLDR
There are three steps to reading in a high precision complex: set precision, read values, declare complex. These steps can be permutated in a variety of orders. Obviously the setting of the precision has to be done before reading the values. But then there are still three different orderings with three different behaviors. Code segment 1 shows that the ordering of (declare complex, set precision, read values) doesn't work because the precision didn't get updated. Code segment 2 shows that the ordering of (set precision, read values, declare complex) works as expected, but is inconvenient because you have to declare the complex components separately. Finally code segment 4 shows that the ordering of (set precision, declare complex, read values) introduces weird rounding errors.
My questions are these: Can anyone explain these discrepancies? How can I declare an std::complex<mpf_class> with a given precision?