Невозможно программно изменить точность повышения кратности mpfr - PullRequest
1 голос
/ 31 марта 2019

Имейте в виду, что точность основана на общем количестве цифр, а не десятичных разрядов, но мне нужен способ установить десятичные разряды, и все, что я могу найти, - это точность, поэтому я пытаюсь с ней работать, поэтому Я учитываю количество цифр во всем числе, чтобы заставить это работать, но это не работает.

Я хочу сделать некоторые математические вычисления и вернуться с заданным значением точности, функция берет строку очень большого числа с очень большой десятичной точностью и возвращает ее в виде строки, в которой указано число десятичных знаков, переданных в качестве точности:

 #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, я знаю, что это другой вопрос, поэтому я просто выкладываю его, чтобы показать, что мои альтернативы не работают лучше с этой точки зрения. Также обратите внимание, что функция деления работает так же, как умножение, я использовал этот пример, чтобы показать, что математика не имеет к этому никакого отношения, но все примеры, которые они мне показывают, не работают должным образом, и я не понимаю, почему просто чтобы прояснить шаги:

  1. Создать серверную часть: typedef boost :: multiprecision :: number> my_mpfr_float;
  2. Установить точность: my_mpfr_float :: default_precision (precision);
  3. Установить начальное значение переменной: my_mpfr_float aThis (mThis.toStdString ());
  4. Если хотите, посчитайте, верните значение с правильной точностью.

Я должен что-то упустить.

Я знаю, что могу просто получить длину строки, и если она больше, чем Precision, то проверить, если Precision + 1 больше 5, если так, добавить 1 в Precision и вернуть подстроку 0, Precision и покончить с Все это Правильный способ делать вещи, я мог бы даже сделать это в JavaScript после возврата, и просто забыть о том, чтобы делать это Правильным способом, но я все еще думаю, что просто что-то упустил, потому что я не могу поверить, что это так на самом деле должен работать.

Отправлено сообщение об ошибке: https://github.com/boostorg/multiprecision/issues/127

...