mpf_class a("0.1")とmpf_class b = 0.1は違うんだなぁ。コンストラクタで呼び出す関数がそれぞれmpf_init_set_strとmpf_set_dなので違うのは当たり前なんだが、そうじゃない。
#include <iostream> #include <gmpxx.h> void dump_mpf_member(mpf_t t) { printf("Prec : %lu\n", t->_mp_prec); printf("Size : %lu\n", t->_mp_size); for (size_t i = 0; i < t->_mp_prec; i++) { printf("_mp_d_[%lu]: %lu\n", i, t->_mp_d[i]); } } int main() { mpf_class a("0.1"); mpf_class b = 0.1; puts("mpf_t a"); dump_mpf_member(a.get_mpf_t()); gmp_printf("%.64Ff\n", a.get_mpf_t()); puts("\nmpf_t b"); dump_mpf_member(b.get_mpf_t()); gmp_printf("%.64Ff\n", b.get_mpf_t());} /* $ ./a.out mpf_t a Prec : 2 Size : 3 _mp_d_[0]: 11068046444225730969 _mp_d_[1]: 11068046444225730969 0.1000000000000000000000000000000000000000000000000000000000000000 mpf_t b Prec : 2 Size : 2 _mp_d_[0]: 0 _mp_d_[1]: 1844674407370955264 0.1000000000000000055510000000000000000000000000000000000000000000 */
b = 0.1
で0.1を評価するときに既に丸め誤差が発生している。0.1+0.1+0.1と0.3が等しくないやつ。一方でmpf_class a("0.1")では忠実に0.1を表現してくれる(限度はありそうやけど、正直わからん)。
ちなみにdouble型をmpf_t->_mp_dにセットする実装はextract-dbl.cにある。見ないほうがいい。
double型をmpf_tにセットしたいとき、単純に_mp_d[0] = double value;
と書いてもダメそうだ。