I have this code in C++:
#include <iostream>
#include <iomanip>
#include <limits>
#include <boost/multiprecision/mpfr.hpp>
using namespace boost::multiprecision;
template<int bity>
auto obliczenie() {
using real = number<mpfr_float_backend<bity>>;
int cyfry = std::numeric_limits<real>::digits10;
std::cout << std::setprecision(cyfry + 2);
real x = 77617;
real y = 33096;
real wynik = real(333.75)*pow(y,6) + pow(x,2)*(real(11)*pow(x,2)*pow(y,2) - pow(y,6) -
real(121)*pow(y,4) -real(2)) + real(5.5)*pow(y,8) + x/(real(2)*y);
return wynik;
}
int main() {
std::cout << "Wynik dla float: " << obliczenie<24>();
std::cout << "\nWynik dla double: "<< obliczenie<53>();
std::cout << "\nWynik dla long double: " << obliczenie<64>();
std::cout << "\nWynik dla float 128: " << obliczenie<113>();
return 0;
}
and it gives me way more precise solutions to this function than my Python script:
import mpmath
def funkcja(bity):
mpmath.mp.prec = bity
x = mpmath.mpf(77617)
y = mpmath.mpf(33096)
return mpmath.mpf(333.75*pow(y,6) + pow(x,2)*(11*pow(x,2)*pow(y,2)
- pow(y,6) - 121*pow(y,4) - 2) + 5.5*pow(y,8) + x/(2*y))
print("\nFloat: " ,funkcja(24))
print("\nDouble: ",funkcja(53))
print("\nLong double: ",funkcja(64))
print("\nFloat 128: ", funkcja(113))
The answers C++ gives me:
Wynik dla float: 1.172603940053178631858835
Wynik dla double: -0.8273960599468213681411650954798162919990331157843848187
Wynik dla long double: -0.827396059946821368141165095479816291999033115784384819917814841671
Wynik dla float 128:
-0.8273960599468213681411650954798162919990331157843848199178148416727096930142615421803239062122310853275320280396423
(-0.827... is the correct answer to this function.)
Python on the other hand:
Float: -6.33825e+29
Double: -1.18059162071741e+21
Long double: 576460752303423489.0
Float 128: 1.17260394005317863185883490452018
I think I gave them the same precision to work with, so I can't understand what is the problem here.
Additionally, the same answer is given by C++ with precision 24, as give by Python with precision 113.
What is the mistake that I'm making here?
You are not using the same precision. mpmath.mp.prec = bity sets the precision in bits (see here). On the other hand, the template argument of mpfr_float_backend is the precision in terms of number of decimal digits (see here).
This explains for example why
Wynik dla float: 1.172603940053178631858835
shows 24 decimal digits (actually you do determine the number of digits via std::numeric_limits<real>::digits10, but it is unnecessary because cyfry is just bity). On the other hand
Float: -6.33825e+29
is limited to 24 bits precision.