将浮点值转换为ascii并再次返回,而不会引入错误

时间:2014-05-27 10:33:11

标签: c++ encoding floating-point ascii

乍一看,这似乎微不足道,但通常(基数2 - 基数10) FP< - > ASCII 转换并不总是在不引入错误的情况下完成。当然,这些都很小,但是有哪些选项可以使转换到ASCII和从ASCII完美转换,也就是说,转换的可能性是什么,而不会引入任何错误?我正在考虑 base64 编码或比特编码(例如像11110101010...这样的东西),这两者都会保留基数。

编辑:由于我无法回答自己,这就是我的想法:

double d{.1};

auto const s(::std::to_string(*reinterpret_cast<::std::uint64_t*>(&d)));
::std::uint64_t n(::std::stoull(s));

auto const e(*reinterpret_cast<double*>(&n));

assert(d == e);

2 个答案:

答案 0 :(得分:2)

你的意思是什么?没有引入错误&#34;?如果它 是为了让机器重读以后,精确到17位数 保证往返:文本中的实际值不会 双精确值,但它会更接近 原始双值比任何其他双值,所以 重新转换为double将导致初始值。如果你 有权访问C ++ 11,你也可以设置格式输出 十六进制值:

std::cout.setf( std::ios_base::fixed | std::ios_base::scientific,
                std::ios_base::floatfield );

在这种情况下,输出应该是精确的,无论如何 精确。

如果是人类阅读,并知道确切的价值,那就有了 标准库中没有任何内容可以保证这一点。在 理论上,输出53位数就足够了,但两者都没有 C ++标准和IEEE标准都要求实现 防止转换例程中的舍入错误 精度,一些实现只是附加一个足够的 在第19或第20位之后的大量'0',而不是 浪费运行时计算错误值。

答案 1 :(得分:2)

我认为你问的问题是如何通过ASCII(字符串)表示来往返浮点双精度值。我同意,为此目的,以固定或浮点十进制表示法打印数字是完全不合适的。

如果你不关心字符串的样子,那么简单的解决办法就是将8字节双精度视为两个整数。两个十六进制整数将占用16个字符位置。通过练习,您甚至可以阅读其中一个并估算其值。

Base-64中的相同内容只会减少字符位置的数量(到11/12)。以这种方式格式化的数字是不可读的。

还有其他方法,但为什么要这么麻烦?这些就足够了。