便携式打印双倍到C++个 iostreams 的指数
Portable printing of exponent of a double to C++ iostreams
我想打印一个双精度值以std::cout
可移植(GCC,clang,MSVC++(,以便输出在所有平台上都相同。
我对指数的格式有问题。以下程序
#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:实际上在迪特马尔的评论之后将"尾数"重命名为"指数"。维基百科上还有一个关于尾数与重要部分。
没有操纵器控制指数的格式(我假设你指的是指数而不是尾数;此外,用于尾数的"官方"名称很重要(。更糟糕的是,我在 C 标准中看不到任何限制指数格式的规则。我意识到这是关于C++但出于格式细节的目的,C++标准是指 C 标准。
我知道的唯一方法是使用自己的std::num_put<char>
方面,根据需要格式化值。然后将这个方面放入一个std::locale
,而又被imbue()
到std::cout
中。潜在的实现可以使用默认的std::num_put<char>
方面(或snprintf()
,不幸的是,可能更简单(来格式化浮点数,然后从指数中去除前导零。
虽然Dietmar的答案是干净且可能唯一真正便携的答案,但我意外地发现了一个快速而肮脏的答案:MSVC 提供了_set_output_format
功能,您可以使用该功能切换到"将指数打印为两位数"。
以下 RAII 类可以在main()
函数中实例化,以提供与 GCC、CLANG 和 MSVC 相同的行为。
class ScientificNotationExponentOutputNormalizer
{
public:
unsigned _oldExponentFormat;
ScientificNotationExponentOutputNormalizer() : _oldExponentFormat(0)
{
#ifdef _MSC_VER
// Set scientific format to print two places.
unsigned _oldExponentFormat = _set_output_format(_TWO_DIGIT_EXPONENT);
#endif
}
~ScientificNotationExponentOutputNormalizer()
{
#ifdef _MSC_VER
// Enable old exponent format.
_set_output_format(_oldExponentFormat);
#endif
}
};
问题是Visual C++没有遵循C99标准。在 Visual C++ 2015 中,由于编译器现在遵循标准,因此删除了_set_output_format
:
%e
和%E
格式说明符将浮点数格式化为十进制尾数和指数。在某些情况下,%g
和%G
格式说明符也会以这种形式设置数字的格式。在以前的版本中,CRT 将始终生成具有三位指数的字符串。例如,printf("%en", 1.0)
将打印1.000000e+000
.这是不正确的:C 要求如果指数只能用一个或两个数字来表示,那么只打印两个数字。在 Visual Studio 2005 中,添加了全局一致性开关:
_set_output_format
。程序可以使用参数_TWO_DIGIT_EXPONENT
调用此函数,以启用符合指数的打印。默认行为已更改为符合标准的指数打印模式。
请参阅 Visual C++ 2015 中的重大更改。对于旧版本,请参阅@Manuel的答案。
仅供参考,在C99标准中,我们可以阅读:
e,E
表示浮点数的双精度参数以 [-]d.ddd e(+-(dd 样式转换,其中小数点字符之前有一个数字(如果参数为非零,则为非零(,小数点字符之后的位数等于精度;如果缺少精度,则取 6;如果精度为零且未指定 # 标志, 不显示小数点字符。该值将舍入到适当的位数。E 转换说明符生成一个数字,其中 E 而不是 e 引入指数。指数始终包含至少两位数字,并且仅包含表示指数所需的更多数字。如果值为零,则指数为零。表示无穷大或 NaN 的双精度参数以 f 或 F 转换说明符的样式进行转换。
与C90相比,这是一个差异,C90没有给出任何关于所需指数长度的指示。
请注意,最近的视觉C++更改还涉及如何打印nan
、inf
等。
- 使用简单类型列表实现的指数编译时间.为什么
- 隐式声明的 boost::iostreams::mapped_file_source 已被弃用
- 如何从组合指数中找到仓位
- 正在读取 obj 文件!(指数)
- C++:快速模块化指数
- 在C++不使用 POW 的情况下处理负指数
- 比较向量中的元素时所花费的时间呈指数级增长
- 如何将包含指数的 QString 转换为C++中的双倍?
- 将数字提高到一个巨大的指数
- 负指数是否必然意味着未定义的行为
- 整数的指数速记
- 在矩阵逆变器上工作,由于某种原因,我的指数循环不起作用
- 自定义提升多精度指数中的位数
- 如何计算复矩阵的指数
- 用C++打印指数形式的素数分解
- 为什么Regex(c++)需要指数时间
- 指数近似不适合小输入或大输入
- 如果 std::numeric_limits<float>::is_iec559 为真,这是否意味着我可以以明确定义的方式提取指数和尾数?
- 使用 BOOST property_tree / iostreams / 文件系统 / foreach - 结果出现链接
- 便携式打印双倍到C++个 iostreams 的指数