【问题标题】:what is the best way to avoid negative zero in output?避免输出负零的最佳方法是什么?
【发布时间】:2012-09-21 18:35:34
【问题描述】:

正如this 问题所说,浮点数中的负零和正零之间存在一些差异。我知道这是因为一些重要的原因。我想知道的是一个简短的代码,以避免输出负零。

例如在以下代码中:

cout << fixed << setprecision(3);
cout << (-0.0001) << endl;

打印“-0.000”。但我想要“0.000”。

请注意,所有其他负数(例如 -0.001)仍应在打印前加上减号,因此简单的 * -1 将不起作用。

【问题讨论】:

  • @TonyTheLion 如果我的号码是 -0.001 怎么办?它应该被打印 -0.001 而我不应该 * -1 这个。
  • AFAIK 一个负数乘以另一个负数得到一个正数。那是基本的数学。你的意思是什么?
  • 在执行 *-1 之前,您必须检查您的数字是否为正数,否则您将得到一个负数作为输出。
  • @TonyTheLion 只有当结果为 -0.000 时,我才应该乘以 -1。并非您所说的所有负数“在执行 *-1 之前,您必须检查您的数字是否为正数”
  • 您似乎在谈论两个不同的事情:负零和一个足够小的负数,打印时它会四舍五入为零,因此具有一定的精度。你想阻止哪个?

标签: c++ floating-point cout


【解决方案1】:

根据您的精度尝试。

cout &lt;&lt; ((abs(ans) &lt; 0.0005)? 0.000: ans) &lt;&lt; endl;

【讨论】:

  • 应该是:'cout
  • @wallyk:不能从 C++ 中的条件表达式返回不同的类型。
  • @wallyk 不需要。因为在此之前调用了 setprecision(3)。
  • @nneonneo:哦,是的。我最近一直在做太多的javascript和php。
  • @Aladdin:&lt;&lt; 的优先级高于 ?:。在C++形式语法中,&lt;&lt;shift-expression → shift-expression &lt;&lt; additive-expression解析,?:conditional-expression → logical-or-expression ? expression : assignment-expression解析。由于语法的其他规则,ans &lt;&lt; endl 可以是assignment-expression,但未加括号的…?…:… 不能是shift-expression。因此,必须使用&lt;&lt; 规则来减少ans &lt;&lt; endl,然后才能减少?: 表达式。
【解决方案2】:

怎么样:

cout << (value == 0.0 ? abs(value) : value)  << endl;

【讨论】:

  • 网上有很多资源可以解释为什么value == 0.0 是个坏主意。 docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html不错
  • 如果提问者真的只想抓住负 0,这个答案是正确的(也是一个好主意)。但问题的主体表明情况并非如此。
  • @IronMensan - 从那篇文章中得到的是“IEEE 标准定义了比较,因此 +0 = -0”......所以我真的很感兴趣 - 你能指出我的一些事情吗?更明确地解释问题?史蒂夫杰索普 - 在我看来,问题的主体只是专门针对负 0 提出的。我错过了什么吗?
  • 是的,问题的主体表明提问者希望打印 "0.000" 而不是 "-0.000"-0.0001。因此,需要特殊处理的不仅仅是负零,-0.0001 也是如此。基本上,提问者将来自cout"-0.000" 的任何输出称为“负零”,它们不仅仅意味着value 中的IEEE 负零。
【解决方案3】:

如果您关心任意精度,而不是只关心 3 的固定精度,则需要做一些工作。基本上,您必须在 cout 之前进行预检查,以查看数字是否会以您不喜欢的方式格式化。

你需要找到数字的数量级,看看是否会丢失不精确的数字,只留下符号位。

您可以使用数字绝对值的以 10 为底的对数来执行此操作。如果结果的负数大于您设置的精度,则该数字将以您不希望的方式显示。

0.0001 的 log10 是 -4。

(-4) 的负数是 4。

4 > 3(任意精度) 因此,该值将不愉快地显示出来。

在非常糟糕的伪代码中:

float iHateNegativeZeros(float theFloat, int precision)
{
   if((theFloat < 0.0f) &&
      (-log10(abs(theFloat)) > precision))
   {
     return -theFloat;
   }
   else
   {  
     return theFloat;
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-12
    • 2019-08-23
    • 2014-12-15
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 2010-09-08
    相关资源
    最近更新 更多