c++ - Visual Studio 2012 和 Visual Studio 2015 的双重结果不同
问题描述
我正在 Windows 7、64 位上开发数学应用程序。我们最近通过 Visual Studio 2015 迁移到 c++11 我有一个问题,我已将其简化为以下小程序
#include "stdafx.h"
#include "iostream"
using namespace std;
int main()
{
const double OM = 1.10250000000000000E-36;
std::cout.precision(20);
std::cout << OM;
int y;
std::cin >> y;
return 0;
}
当我编译并运行程序时 1) 在 Visual Studio 2012 上,我得到的结果为1.1025000000000001e-036 2) 在 Visual Studio 2015 上使用 c++11 ,我得到的结果为1.1025000000000000611e-36
注意 Visual Studio 2012 中额外的 0。我们需要得到相同的结果。(注意结果不同,不仅是额外的 0,而且最后显示的数字也不同)
我怎样才能使这些相同(即我需要带有额外 0 的旧结果)?这给我带来了很多问题,我希望得到同样的结果。
需要相同结果的原因。上面这个程序是对差异的一个小解释。这种差异导致我的回归失败。有时这种差异加起来会产生不同的结果。
我希望 Visual Studio 有一些编译器开关等可能会给我旧的结果。
解决方案
具有三位指数的 Visual C++ 的旧方式似乎是_set_output_format已弃用的 Visual C++ 扩展。文档说:
重要的
此功能已过时。从 Visual Studio 2015 开始,它在 CRT 中不可用。
所以基本上,你运气不好,但并非没有希望。
您可以为 double 定义自己的打印功能,并将其链接到std::basic_ostream
through std::ios_base::imbue
。这意味着您必须仅为您的需要定义一个新的语言环境。
这是解决方案的草图。您必须填写详细信息,以便代码与所有iostream
格式选项一起正常工作,并且不会忽略setprecision()
. 下面的示例代码只是一个示例,它并没有做所有这些事情。要获得完整的解决方案,您必须做一些工作(但不要太多):
template <class Char>
class my_double : public std::num_put<Char>
{
public:
static my_double * get()
{
static my_double * singleton = new my_double;
return singleton;
}
private:
using base = std::num_put<Char>;
//
// This method will format your double according to your needs.
// Refine the code so that it reads and uses all the flags from `str`
// and uses the `fill` character.
//
iter_type do_put(iter_type out, std::ios_base& str, Char fill, double v) const override
{
if (v < 0)
{
v *= -1;
*out = '-';
++out;
}
if (v == 0.0 || std::isnan(v))
{
return base::do_put(out, str, fill, v);
}
auto exponent = static_cast<int>(std::floor(std::log10(v)));
auto significand = v / std::pow(10.0, exponent);
// TODO: Format according to the flags in `str`
out = base::do_put(out, str, fill, significand);
*(out++) = 'e';
if (exponent < 0)
{
*(out++) = '-';
exponent *= -1;
}
*(out++) = '0' + ( (exponent / 100) % 10);
*(out++) = '0' + ((exponent / 10) % 10);
*(out++) = '0' + (exponent % 10);
return out;
}
};
int main()
{
// !!!
// This is how you register your formatting function for `double`
// !!!
std::cout.imbue(std::locale(cout.getloc(), my_double<char>::get()));
/// your code goes here:
}
推荐阅读
- python - pyspark concat_ws 用于数组到字符串
- php - 如何让活动的 PHP 文件在 Microsoft Visual Code 中运行?
- docker - 如何在 ubuntu 容器中使用 docker
- bash - 使用 PKI 对 bash 应用程序实施限制
- python - 使用 Seaborn 绘制条形图
- powerbi - Power BI 查询按顺序运行
- javascript - NODE.JS - 检查对象中是否有意外字段
- html - 动画后接收指针事件的链接在 Safari 中不可点击
- javascript - 访问从服务器端(Node.js)的 Swift 客户端发送的 HTTP 请求的正文?
- java - spring 从 xml 文件中获取 bean 时出错