C++11:将 `double` 打印为十六进制?

C++11: Print `double` as hex?

我需要将 IEEE 64 位 double 打印为十六进制字符串。

我使用的语言是C++11。不多也不少。

But how to get the state of the stream right before that so it can be reset to the initial state?

您可以使用流的 flags() function to retrieve and save the current settings, then later use the setf() 函数来恢复它们,确保在 "mask"(第二个参数)中包含 std::ios_base::floatfield

Must the precision also be hacked if the goal is to print with the highest possible precision? Or is that already a feature of hexfloat?

是的。来自 cppreference:

Hexadecimal floating-point formatting ignores the stream precision specification, as required by the specification of 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;
}

我需要这个的项目实际上使用的比 C++11 多一点,即 GMP 支持来自 C99 的打印修饰符 %a

// 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;
}