这是Clang的错误还是我的错误?

时间:2018-03-21 01:24:04

标签: c++ floating-point clang rounding

运行以下C ++程序两次。一次使用给定的析构函数,一次从析构函数中删除std::fesetround(value);。为什么我会收到不同的输出?在函数add之后不应该调用析构函数吗?我在http://cpp.sh/和Clang ++ 6.0以及g ++ 7.2.0上运行了两个版本。对于g ++,我在源代码中也包含#pragma STDC FENV_ACCESS on,没有任何改变。

#include <iostream>
#include <string>
#include <cfenv>

struct raii_feround {
  raii_feround() : value(std::fegetround()) {    }
 ~raii_feround() { std::fesetround(value); }
  inline void round_up  () const noexcept { std::fesetround(FE_UPWARD  ); }
  inline void round_down() const noexcept { std::fesetround(FE_DOWNWARD); } 
  template<typename T>
  T add(T fst, T snd) const noexcept { return fst + snd; }
private: 
  int value; };

float a = 1.1;
float b = 1.2;
float c = 0;
float d = 0;

int main() {   
    {
        raii_feround raii;
        raii.round_up();
        c = raii.add(a, b);
    }
    {
        raii_feround raii;
        raii.round_down();
        d = raii.add(a, b);
    }
    std::cout << c << "\n"; // Output is: 2.3
    std::cout << d << "\n"; // Output is: 2.3 or 2.29999
}

2 个答案:

答案 0 :(得分:1)

使用浮点环境工具需要将#pragma STDC FENV_ACCESS on插入源中(或确保它们默认为on用于您正在使用的实现。(尽管STDC是C要素,C ++标准说这些工具是通过<cfenv>标头导入C ++的。)

在cpp.sh执行此操作会导致“警告:忽略#pragma STDC FENV_ACCESS [-Wunknown-pragmas]”。

因此,cpp.sh上的编译器不支持访问和修改浮点环境。

答案 1 :(得分:0)

我需要做的就是在代码中调用std::cout << std::setprecision(30);之前执行std::coutiomanip也应该包含在内)。