Преобразование числа с плавающей запятой в строку с помощью MPFR

Я хочу преобразовать число с плавающей запятой MPFR в строку. Если я запускаю свою программу, строка генерируется, но без "." в номере. Как я могу сделать это правильно?

#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <mpreal.h>

using mpfr::mpreal;
using std::cout;
using std::endl;

int main (int ac, char *av[])
{
    char data[255];
    mpreal x = 42.0, y = 3.14159265358979323846, res = 0.0;
    mp_exp_t exponent = 10;

    // string data_str[256];

    int precision = 50;
    res = x * y;

    cout.precision(100);
    cout << res;
    cout << "\n";

    // if (mpfr_snprintf (data, 254, "%.20Ff", res.mpfr_srcptr()) < 0)
/*
    if (mpfr_snprintf (data, 254, "%.20Ff", res.mpfr_srcptr()) < 0)
    {
        cout << "gmp_prints_float: error saving string!\n";
    }
    */

    mpfr_get_str ((char *) &data, &exponent, 10, precision, res.mpfr_srcptr(), GMP_RNDN);

    cout << data;
    cout << "\n";

     mpfr_free_cache ();
}

131.946891450771317977341823279857635498046875 13194689145077131797734182327985763549804687500000

В строке вывода нет десятичной точки!


person user2759621    schedule 25.09.2019    source источник
comment
Согласно документам это должно вести себя так.   -  person NathanOliver    schedule 25.09.2019


Ответы (2)


Из документации

Сгенерированная строка представляет собой дробь с неявной точкой счисления сразу слева от первой цифры. Например, число -3,1416 будет возвращено как "-31416" в строке, а 1 будет записано в expptr.

Вам решать, как сгенерировать удобочитаемое представление строки и показателя степени.

Альтернативой может быть использование mpfr_sprintf.

person n. 1.8e9-where's-my-share m.    schedule 25.09.2019
comment
Спасибо каждому за помощь! - person user2759621; 26.09.2019

Функция mpfr_get_str MPFR копируется в функцию mpf_get_str GMP, что объясняет, почему было выбрано не писать десятичную точку. Есть два решения, чтобы иметь десятичную точку:

  1. Используйте mpfr_sprintf (или какой-либо вариант), как предлагается в этом ответе. Я бы порекомендовал это решение (возможно, если вы не хотите игнорировать локали), так как оно является наиболее гибким в формате вывода и не нуждается в исправлении.
  2. Если вам просто нужна мантисса с явной десятичной точкой, используйте mpfr_get_str, но с указателем buffer+1 вместо buffer. Затем сделайте что-то вроде (не обращая внимания на локали)
    int neg = buffer[1] == '-';
    if (neg)
      buffer[0] = '-';
    buffer[neg] = '.';

после фильтрации особых случаев (NaN и бесконечности).

person vinc17    schedule 26.09.2019