C ++中

时间:2017-03-12 16:39:14

标签: c++ math floating-point

我正在尝试修改一个简单的数学程序,并且我很难获得正确的格式化输出。

以下是示例代码:

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

const double PI = 3.14159265358979;

int main()
{
        double a,b,c,d;

        a = cos(30*PI/180);
        b = sin(30*PI/180);
        c = cos(90*PI/180);
        d = sin(90*PI/180);

        cout << a << endl;
        cout << b << endl;
        cout << c << endl;
        cout << d << endl;
}

给出以下输出:

  

0.866025
  0.5
  1.61554e-015
  1

我尝试使用round如下,但round将围绕所有这些

cout << round(a) << endl;
cout << round(b) << endl;
cout << round(c) << endl;
cout << round(d) << endl;  

给出以下输出:

  

1
  0
  0
  1

最后我尝试修复但是它已经修复了所有

cout << fixed << a << endl;
cout << fixed << b << endl;
cout << fixed << c << endl;
cout << fixed << d << endl;

输出

  

0.866025
  0.500000
  0.000000
  1.000000

我想要的是输出输出,如:

  

0.866025
  0.5
  0
  1

我知道浮点数很难处理,因为有限的存储空间代表了无限制。

我经历了很多关于浮点数的读数,但是没有找到如何仅使用标准C ++库获得所需的结果。

因为角度30和90只是一个样本,我不能为每个变量使用不同的输出技术。

我希望尽可能长时间地坚持使用cout而不是printf。

我提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我认为违规输出是使用科学记数法的c输出。如果是这样,您需要单独处理这些值:灵活格式(std::ios_base::fixedstd::ios_base::scientific都未设置且格式等同于使用printf()&# 39; s %g format)将以一种方式打印值,该方式尽可能地表示具有设定精度的值。当合理表示该值所需的位数时,此方法将使用科学记数法。

处理这种情况的一种方法是明确检测&#34;坏&#34;值,例如低于某个阈值的值。如果您想避免单独检查每个输出,可以imbue()使用自定义std::locale方面的自定义std::num_put<...>对象,例如:

#include <iostream>
#include <locale>
#include <iomanip>
#include <cmath>

const double PI = 3.14159265358979;

struct num_put: std::num_put<char> {
    iter_type do_put(iter_type to, std::ios_base& fmt, char_type fill, double v) const {
        if (v < 1e-4) {
            *to = '0';
            ++to;
            return to;
        }
        return std::num_put<char>::do_put(to, fmt, fill, v);
    }
};

int main()
{
    std::cout.imbue(std::locale(std::locale(), new num_put));

        double a,b,c,d;

        a = std::cos(30*PI/180);
        b = std::sin(30*PI/180);
        c = std::cos(90*PI/180);
        d = std::sin(90*PI/180);

        std::cout << a << '\n';
        std::cout << b << '\n';
        std::cout << c << '\n';
        std::cout << d << '\n';
}

这个快速演示还解决了一些不相关的问题:

  • 不要使用std:endl:如果您要明确刷新流,请使用std::flush
  • using指令不好