Потеря точности при расчете величин & lt; 1 с величинами & gt; 1

Я тестирую построенную строку gmp_float.

Этот код

#include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/gmp.hpp>
#include <iostream>

using namespace boost::multiprecision;

typedef number<gmp_float<15>> mp_type;

int main()
{
mp_type total("1.01");
cout << total.str(0) << endl;
mp_type first_addition(".01");
cout << first_addition.str(0) << endl;
total += first_addition;
cout << total.str(0) << endl;
}

печать

1.01
0.01
1.01999999999999999998

Зачем? Я провел больше тестов, и в данном конкретном случае не имеет значения, что это за операция, если величина одного числа> 0 и <1, а у другого -> 1.

По ссылке выше

Невозможно выполнить обход объектов этого типа в строку и обратно и получить обратно одно и то же значение. Похоже, что это ограничение GMP.

Есть ли другие зоны, где точность теряется?

2

Решение

Boost Multiprecision также имеет десятичные числа с плавающей точкой:

Видеть это Жить на Колиру печатает:

clang++ -std=c++11 -Os -Wall -pedantic main.cpp && ./a.out
1.01
0.01
1.02

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

using namespace boost::multiprecision;
using std::cout;
using std::endl;

typedef cpp_dec_float_50 mp_type;

int main()
{
mp_type total("1.01");
cout << total.str(0)          << endl;

mp_type first_addition(".01");
cout << first_addition.str(0) << endl;

total += first_addition;
cout << total.str(0)          << endl;
}
2

Другие решения

mpf_t в GMP является двоичный число с плавающей точкой. 0.01 не является точно представимым в виде двоичного числа с плавающей запятой любой конечной точности.

изменения 0.01 за 0.125 а также 1.01 за 1.125 заставляет отформатированный вывод выглядеть хорошо. Это потому что 0.125 а также 1.125 точно представлены в виде двоичных чисел с плавающей запятой, по крайней мере, с 8 битами

2