C++11:将 `double` 打印为十六进制?
C++11: Print `double` as hex?
我需要将 IEEE 64 位 double
打印为十六进制字符串。
我知道我必须以某种方式使用 std::hexfloat
。但是如何在此之前获取流的状态以便将其重置为初始状态?
如果目标是以尽可能高的精度打印,精度是否也必须被破解?或者这已经是 hexfloat 的一个特性了吗?
输出的方式必须能够在 C/C++ 源中使用而无需任何进一步的麻烦,例如-0x123.abc42p+10
.
我使用的语言是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;
}
我需要将 IEEE 64 位 double
打印为十六进制字符串。
我知道我必须以某种方式使用
std::hexfloat
。但是如何在此之前获取流的状态以便将其重置为初始状态?如果目标是以尽可能高的精度打印,精度是否也必须被破解?或者这已经是 hexfloat 的一个特性了吗?
输出的方式必须能够在 C/C++ 源中使用而无需任何进一步的麻烦,例如
-0x123.abc42p+10
.
我使用的语言是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;
}