便携式打印双精度指数到 C++ iostreams
我想以可移植方式(GCC、clang、MSVC++)将双精度值打印到 std::cout,以便所有平台上的输出都相同。
我的指数格式有问题。 以下程序
#include <iostream>
int main()
{
std::cout << 0.1e-7 << std::endl;
return 0;
}
在 GCC 中具有此输出:
1e-08
在 MSVC 中具有以下输出
1e-008
我怎样才能使两个输出相同?
如果这是一个愚蠢的问题,我很抱歉,但到目前为止我还没有找到答案。 所有格式似乎都是围绕尾数之前所有内容的格式演变的...
编辑:GCC 的输出是 1e-08
而不是 1e-8
(如最初所述),所以它符合。抱歉造成混乱。
编辑2:实际上按照迪特马尔的评论将“尾数”重命名为“指数”。 维基百科上还有一个关于尾数与有效位数的部分。
I want to print a double value to std::cout
portably (GCC, clang, MSVC++) such that the output is the same on all platforms.
I have a problem with the formatting of the exponent.
The following program
#include <iostream>
int main()
{
std::cout << 0.1e-7 << std::endl;
return 0;
}
Has this output with GCC:
1e-08
and the following output with MSVC
1e-008
How can I make both outputs the same?
I'm sorry if this is a dumb question but I have not found an answer so far.
All formatting seems to evolve around the formatting of everything before the mantissa...
EDIT: The output of GCC is 1e-08
not 1e-8
(as originally stated) so it is conforming. Sorry for the confusion.
EDIT2: Actually renamed "mantissa" to "exponent" following Dietmar's remark. There also is a section on Wikipedia on mantissa vs. significant.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
没有操纵器控制指数的格式(我假设您指的是指数而不是尾数;此外,用于尾数的“官方”名称有意义)。更糟糕的是,我在 C 标准中看不到任何限制指数格式的规则。我意识到这是关于 C++ 的,但出于格式细节的目的,C++ 标准指的是 C 标准。
我知道的唯一方法是使用自己的方面(或不幸的是,可能更简单的
std::num_put
方面,根据需要格式化值。然后,这个方面将被放入std::locale
中,而该imbue()
又被imbue()
编辑到std::cout
中。潜在的实现可以使用默认的 std::num_putsnprintf()
)来格式化浮点数,然后从指数中去除前导零。There is no manipulator controlling the formatting of the exponent (I assume you mean the exponent rather than the mantissa; also, the "official" name used for the mantissa is significant). To make matters worse, I can't see any rule in the C standard which restricts the formatting of the exponent. I realize that this is about C++ but for the purpose of the formatting details, the C++ standard refers to the C standard.
The only approach I'm aware of is to use an own
std::num_put<char>
facet which formats the values as desired. This facet would then be put into astd::locale
which in turn isimbue()
ed intostd::cout
. A potential implementation could use the defaultstd::num_put<char>
facet (orsnprintf()
which is, unfortunately, probably simpler) to format the floating point number and then strip leading zeros from the exponent.虽然 Dietmar 的答案是干净的,而且可能是唯一真正便携的答案,但我意外地发现了一个快速而肮脏的答案:
MSVC 提供了
_set_output_format
函数,您可以用于切换到“将指数打印为两位数”。可以在您的
main()
函数中实例化以下 RAII 类,为您提供与 GCC、CLANG 和 MSVC 相同的行为。While Dietmar's answer is the clean and probably only really portable answer, I accidentally found a quick-and-dirty answer:
MSVC provides the
_set_output_format
function which you can use to switch to "print exponent as two digits".The following RAII class can be instantiated in your
main()
function to give you the same behaviour of GCC, CLANG and MSVC.问题是 Visual C++ 没有遵循 C99 标准。在 Visual C++ 2015 中,
_set_output_format
已被删除,因为编译器现在遵循标准:请参阅 Visual C++ 2015 中的重大更改 。对于旧版本,请参阅@Manuel 的答案。
仅供参考,在 C99 标准中,我们可以阅读:
与 C90 相比,这是一个差异,C90 没有给出任何有关所需指数长度的指示。
请注意,最近的 Visual C++ 更改还涉及如何打印
nan
、inf
等。The problem is that Visual C++ was not following the C99 standard. In Visual C++ 2015,
_set_output_format
was removed since the compiler now follows the standard:See Breaking Changes in Visual C++ 2015. For older versions, see @Manuel's answer.
FYI, in the C99 standard, we can read:
This is a difference compared to C90 that did not give any indication concerning the required exponent length.
Note that the recent Visual C++ changes also concern how to print
nan
,inf
etc.