Имейте в виду, что точность основана на общем количестве цифр, а не десятичных разрядов, но мне нужен способ установить десятичные разряды, и все, что я могу найти, - это точность, поэтому я пытаюсь с ней работать, поэтому Я учитываю количество цифр во всем числе, чтобы заставить это работать, но это не работает.
Я хочу сделать некоторые математические вычисления и вернуться с заданным значением точности, функция берет строку очень большого числа с очень большой десятичной точностью и возвращает ее в виде строки, в которой указано число десятичных знаков, переданных в качестве точности:
#include <boost/multiprecision/mpfr.hpp>
QString multiply(const QString &mThis, const QString &mThat, const unsigned int &precison)
{
typedef boost::multiprecision::number<mpfr_float_backend<0> > my_mpfr_float;
my_mpfr_float aThis(mThis.toStdString());
my_mpfr_float aThat(mThat.toStdString());
my_mpfr_float::default_precision(precison);
my_mpfr_float ans = (aThis * aThat);
return QString::fromStdString(ans.str());
}
Я пробовал без typedef, та же проблема;
MathWizard :: multiply ("123456789.123456789", "123456789.123456789", 20);
18 цифр точности, 9 + 9, я должен попросить 30
вернет 22 десятичных знака
+15241578780673678,51562
вместо 20
15241578780673678,516
Так почему же это на 2?
Я бы хотел изменить точность после математики, но, похоже, вам нужно установить ее раньше, а не как примеры, которые Boost показывает в своем примере, но все равно не возвращает правильное значение, делая это после не изменить значение.
Обновление: сравните то, что я сделал, с тем, что, как они говорят, работает в этом посте:
как изменить точность во время выполнения с помощью boost :: multiprecision
typedef number<gmp_float<0> > mpf_float;
mpfr_float a = 2;
mpfr_float::default_precision(1000);
std::cout << mpfr_float::default_precision() << std::endl;
std::cout << sqrt(a) << std::endl; // print root-2
Я заметил различия между gmp_float, mpf_float (используя boost / multiprecision / gmp.hpp) и mpfr_float, а mpfr_float даст мне более точную точность, например, если я возьму число (1/137):
mpf_float
0.007299270072992700729927007299270072992700729927007299270073
only 1 Precision, 23 digits when set to 13
0.00729927007299270072993
mpfr_float
0.007299270072992700729929
only 1 Precision, 16 digits when set to 13
0.0072992700729928
Имея только 1 Точность, я ожидаю, что мой ответ будет на один десятичный знак меньше.
Другие типы данных работают аналогично, я пробовал их все, поэтому этот код будет работать одинаково для всех типов данных, описанных здесь:
повышение 1.69.0: мультиточность Глава 1
Я также должен отметить, что я полагаюсь на Qt, так как эта функция используется в приложении QtQuick Qml Felgo, и на самом деле я не мог понять, как преобразовать это в строку без преобразования ее в экспоненту, хотя я использовал ans. str () для обоих, я предполагаю, что fromStdString делает что-то другое, чем std :: string (ans.str ()).
Я полагаю, что если я не смогу его выяснить, я просто сделаю скругление строк, чтобы получить правильную точность.
std::stringstream ss;
ss.imbue(std::locale(""));
ss << std::fixed << std::setprecision(int(precison)) << ans.str();
qDebug() << "divide(" << mThis << "/" << mThat << " @ " << precison << " =" << QString::fromStdString(ss.str()) << ")";
return QString::fromStdString(ss.str());
Я все еще не мог уйти без использования QString, но это не сработало, оно возвращает 16 цифр вместо 13, я знаю, что это другой вопрос, поэтому я просто выкладываю его, чтобы показать, что мои альтернативы не работают лучше с этой точки зрения. Также обратите внимание, что функция деления работает так же, как умножение, я использовал этот пример, чтобы показать, что математика не имеет к этому никакого отношения, но все примеры, которые они мне показывают, не работают должным образом, и я не понимаю, почему просто чтобы прояснить шаги:
- Создать серверную часть: typedef boost :: multiprecision :: number> my_mpfr_float;
- Установить точность: my_mpfr_float :: default_precision (precision);
- Установить начальное значение переменной: my_mpfr_float aThis (mThis.toStdString ());
- Если хотите, посчитайте, верните значение с правильной точностью.
Я должен что-то упустить.
Я знаю, что могу просто получить длину строки, и если она больше, чем Precision, то проверить, если Precision + 1 больше 5, если так, добавить 1 в Precision и вернуть подстроку 0, Precision и покончить с Все это Правильный способ делать вещи, я мог бы даже сделать это в JavaScript после возврата, и просто забыть о том, чтобы делать это Правильным способом, но я все еще думаю, что просто что-то упустил, потому что я не могу поверить, что это так на самом деле должен работать.
Отправлено сообщение об ошибке: https://github.com/boostorg/multiprecision/issues/127