2015-11-03 8 views
5

Sto eseguendo una simulazione di esperimenti fisici, quindi ho bisogno di una precisione in virgola mobile molto elevata (più di 16 cifre). Uso Boost.Multiprecision, tuttavia non riesco a ottenere una precisione superiore a 16 cifre, indipendentemente da ciò che ho provato. Corro la simulazione con C++ e compilatore Eclipse, ad esempio:virgola mobile di precisione più elevata utilizzando boost lib (superiore a 16 cifre)

#include <boost/math/constants/constants.hpp> 
#include <boost/multiprecision/cpp_dec_float.hpp> 
#include <iostream> 
#include <limits> 

using boost::multiprecision::cpp_dec_float_50; 

void main() 
{ 
    cpp_dec_float_50 my_num= cpp_dec_float_50(0.123456789123456789123456789); 
    std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10); 
    std::cout << my_num << std::endl; 
} 

L'output è:

0.12345678912345678379658409085095627233386039733887 
       ^

ma dovrebbe essere:

0.123456789123456789123456789 

Come si può vedere, dopo il 16 cifre non è corretto. Perché?

risposta

11

il problema è qui:

cpp_dec_float_50 my_num = cpp_dec_float_50(0.123456789123456789123456789); 
              ^// This number is a double! 

Il compilatore non utilizza precisione arbitraria letterali in virgola mobile, e utilizza invece IEEE-754 doppie, aventi precisione finita. In questo caso, il più vicino double al numero che avete scritto è:

0.1234567891234567837965840908509562723338603973388671875 

e la stampa al decimale 50 ° in effetti dare l'uscita che si sta osservando.

quello che vuoi è di costruire il galleggiante precisione arbitraria da una stringa invece (demo):

#include <boost/math/constants/constants.hpp> 
#include <boost/multiprecision/cpp_dec_float.hpp> 
#include <iostream> 
#include <limits> 

using boost::multiprecision::cpp_dec_float_50; 

int main() { 
    cpp_dec_float_50 my_num = cpp_dec_float_50("0.123456789123456789123456789"); 
    std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10); 
    std::cout << my_num << std::endl; 
} 

uscita:

0.123456789123456789123456789 
2

Il problema è che il compilatore C++ converte i numeri in raddoppia durante la compilazione (anche io, learned, qualche tempo fa). Devi usare funzioni speciali per gestire più punti decimali. Vedere lo Boost documentation o altro answers qui su SO per gli esempi.

Detto questo, è quasi impossibile che ci sia un reale bisogno di così alta precisione. Se perdi precisione, dovresti prendere in considerazione altri algoritmi in virgola mobile anziché aumentare ciecamente il numero di decimali.

Problemi correlati