在 C++ 中转储十六进制浮点数
Posted
技术标签:
【中文标题】在 C++ 中转储十六进制浮点数【英文标题】:Dump hex float in C++ 【发布时间】:2014-01-06 21:49:49 【问题描述】:我尝试了以下操作:
std::cout << std::hex << 17.0625;
但它以十进制转储它。我想看看 11.01(十六进制的 17.0625)。如何以十六进制打印一些浮点值?
请不要提供以下解决方案:
void outhexdigits(std::ostream& out, fp_t d, int max_chars=160)
while(d > 0. && max_chars)
while(d < 1. && max_chars)
out << '0';
--max_chars;
d*=16;
if (d>=1. && max_chars)
int i = 0;
while (d>=1.)
++i, --d;
out << std::hex << i;
--max_chars;
有没有办法在 STL/boost 中以十六进制转储浮点数?
【问题讨论】:
老实说,我发现 C++ 在输出这种格式的表单时非常烦人。在这些情况下,我使用 C 风格的格式化打印。 您需要将memcpy
转换为int
,并打印其十六进制表示。 memcpy
是将构成一种类型对象的位视为另一种类型而不遇到未定义行为的唯一安全方法(您会遇到未指定的行为,并且由您决定是否知道这些位构成有效的@987654327 @ 表示)。
你想要double
的内存布局的十六进制表示还是以16为基数打印人类可读的FP值?
另外,std::hexfloat
。
@JBL 也许你看到了通过指针的类型双关语? reinterpret_cast<int*>(&f);
但是,由于别名规则,这只是未定义的行为。
【参考方案1】:
其他人已经提出了 C++11 解决方案,但您的问题没有 C++11 标记。这是一个 ISO C99 解决方案,使用来自 ISO C99 标准的 %a
和 %la
格式说明符。
我想查看 11.01(十六进制的 17.0625)。
以下程序打印0X1.11P+4
。
#include <stdio.h>
int main()
double x = 17.0625;
printf("17.0625 in hexadecimal is: %A\n", x);
这是一个示例,展示如何以十六进制格式读取和写入浮点数。
#include <stdio.h>
int main()
double x = 0.1;
char* str = "0X1.999999999999AP-4";
printf("0.1 in hexadecimal is: %A\n", x);
printf("Now reading %s\n", str);
/* in a production code I would check for errors */
sscanf(str, "%lA", &x); /* note: %lA is used! */
printf("It equals %g\n", x);
如果可移植性很重要,或者您被较旧的编译器卡住,我认为这是一种合理的方法。
【讨论】:
谢谢,它很好的解决方案。但是,我认为它不会与 boost::multiprecision 一起使用。在将此标记为答案之前,我会尝试一些 boost::tr1 解决方案。 @Sergei 我认为没有任何标准解决方案可以与 boost::multiprecision 一起使用。 A quick google search 似乎表明已计划对 boost::multiprecision 的序列化支持,但在 boost 中尚不可用。 我希望 P+1 与 P+4,显然它是位而不是像我预期的那样。【参考方案2】:试试cout << std::hexfloat << 1.0625;
这需要 C++11。
【讨论】:
根据gcc.gnu.org/onlinedocs/libstdc++/manual/…,它尚未在 GCC 中实现。任何跨平台模拟? boost::tr1? 在 GCC 5.3 上试过,它可以工作。但仍然不适用于 boost::multiprecision。【参考方案3】:std::hexfloat
是一个格式操纵器,用于以十六进制表示形式打印浮点值。它自 2011 年标准以来一直存在。
【讨论】:
以上是关于在 C++ 中转储十六进制浮点数的主要内容,如果未能解决你的问题,请参考以下文章