C++11:将 "double "打印成十六进制?

问题描述 投票:2回答:1

我需要打印一个IEEE 64位的 double 作为十六进制字符串。

  • 我知道我必须用 std::hexfloat 以某种方式。但是,如何在这之前就得到流的状态,从而将其复位到初始状态呢?

  • 如果目标是以尽可能高的精度来打印的话,是否也必须黑掉精度?还是说这已经是hexfloat的一个特性?

  • 输出的方式必须是可以在CC++源码中使用的,而不需要再多说什么,如 -0x123.abc42p+10.

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

c++ c++11 floating-point ieee-754
1个回答
1
投票

但如何在这之前得到流的状态,使它可以被重置到初始状态?

你可以使用流的 flags() 功能来检索和保存当前设置,然后再使用 setf() 函数来恢复它们,并确保包括 std::ios_base::floatfield 中的 "掩码"(第二个参数)。

如果目标是以尽可能高的精度来打印,精度是否也必须被破解?还是说这已经是hexfloat的一个特性?

是的。从 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
投票

我所需要的这个项目使用的东西比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;
}
© www.soinside.com 2019 - 2024. All rights reserved.