如何摆脱C ++中的-0

时间:2016-01-19 19:45:38

标签: c++ floating-point

我正在编写一个程序,其中对浮点数执行一些操作。调试程序后,我开始知道对于特定的测试用例,variable equals -2.38418579e-07的值。现在我将cout精度设置为小数点后的2位数。因此,当我打印它时,它将其打印为-0.00。

但是,我希望输出为0.00而不是-0.00。我已经尝试了变量值的各种if条件。但是,他们没有帮助。任何人都可以建议如何摆脱C ++中的-0.00

3 个答案:

答案 0 :(得分:3)

首先,您应该将容差数定义为阈值,其中任何浮点数低于此阈值的绝对值将被视为零。例如,您可以将此阈值定义为:

#define zero 1e-6

然后你可以使用以下构造来"过滤"你的浮点数:

template<typename T>
std::enable_if_t<std::is_floating_point<T>::value, T> sanitize(T &&num) {
  return std::abs(num) < zero? T{} : num;    
}

Live Demo

请注意,我使用SFINAE以使sanitize函数仅接受作为输入的浮点数。

答案 1 :(得分:0)

  

我希望输出为0.00而不是-0.00

我更喜欢其他答案。但是在紧张的情况下你总是可以使用暴力......(你确定你可以忽略实际的结果吗?)

std::string rslt;
{
   std::stringstream ss;
   ss << variable;  // use same formatting as in your example

   size_t minusSignIndx = ss.str().find("-0.00");

   if (minusSignIndx != std::string::npos)
      rslt = " 0.00"; // found the nasty, ignore it
   else
      rslt = ss.str(); // not nasty, use it
}
//... use rslt

答案 2 :(得分:0)

问题是某个间隔[low,-0.0]中的每个浮点都会打印“-0.00”。

因此你必须找到低点:

  • 使得印刷品(前身(低))=&gt; “-0.01”
  • 使得print(low)=&gt; “-0.00”

然后,你将能够写出类似(南分开......)

的东西
double filter(double x) {
    double low = ... ;
    return (x < low)
        ? x
        : ((x > 0.0)
            ? x
            : 0.0) ;
}

如果你有一个正确舍入的printf,并且使用适当的编译器标志来管理你的算术严格符合IEEE754,那么low的确切值是最接近-1/200的两倍,大于-1/200(我写1 / 200而不是-0.005,因为我说的是十进制值,而不是双数)

我们使用正确舍入的sscanf(“ - 0.005”,“%lf”,d):双重结果小于-1/200。我确实用精确的算法检查了一下,例如在Pharo Smalltalk语言中找到的:

[-0.005 < (-1/200) and: [-0.005 successor > (-1/200)]] assert.

它的后继者大于-1/200(必然,上面的检查只是万无一失)。

因此你可以写(注意&lt; = low):

double filter(double x) {
    double low = 0.005 ;
    return (x <= low)
        ? x
        : ((x > 0.0)
            ? x
            : 0.0) ;
}