C ++ 11: Вывести `double` как hex? - PullRequest
2 голосов
/ 22 апреля 2020

Мне нужно напечатать IEEE 64-битную double в виде шестнадцатеричной строки.

  • Я понимаю, что мне нужно каким-то образом использовать std::hexfloat. Но как получить состояние потока прямо перед этим, чтобы его можно было сбросить до исходного состояния?

  • Должна ли быть взломана точность, если целью является печать с максимально возможным точность? Или это уже особенность hexfloat?

  • Вывод должен быть таким, чтобы его можно было использовать в источнике C / C ++ без каких-либо дополнительных действий, например, -0x123.abc42p+10.

Я использую язык C ++ 11. Не больше, не меньше.

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Но как получить состояние потока прямо перед этим, чтобы его можно было сбросить до исходного состояния?

Вы можете использовать поток flags() функция для извлечения и сохранения текущих настроек, затем позднее используйте функцию setf() для их восстановления, обязательно включив std::ios_base::floatfield в «маску» (второй аргумент) .

Должна ли точность хакерства быть взломана, если целью является печать с максимально возможной точностью? Или это уже особенность hexfloat?

Да. From cppreference :

Шестнадцатеричное форматирование с плавающей точкой игнорирует спецификацию точности потока, как того требует спецификация std :: num_put :: do_put.

Вот небольшая демонстрационная программа, которая может помочь:

#include <iostream>
using std::cout; using std::endl;

int main()
{
    double test = -0x123.abc42p+10;
    cout << std::fixed;         // Change from the default for demo
    cout << test << endl;       // Display in "Current" format
    auto fSave = cout.flags();  // Save current flags
    cout << std::hexfloat;      // Change to HEX float
    cout << test << endl;       // ... and display
    cout.setf(fSave, std::ios_base::floatfield); // Restore float field
    cout << test << endl;       // Restored to previous settings!
    return 0;
}
0 голосов
/ 22 апреля 2020

В проекте, где мне это нужно, используется немного больше, чем в C ++ 11, а именно GMP , который поддерживает модификатор печати %a из C99:

// Include cstdarg / stdarg.h prior to gmp.h in the case
// we want va_list functions like gmp_vfprintf.
#include <cstdarg>
#include <gmp.h>

void func (double d)
{
    gmp_printf ("%a", d);
}

#include <iostream>

void func (std::ostream& ost, double d)
{
    auto len = gmp_snprintf (nullptr, 0, "%a", d);
    char str[1 + len];
    gmp_sprintf (str, "%a", d);
    ost << str;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...