C中的负十进制回合

时间:2015-08-05 11:46:32

标签: c double

我需要在C程序中将十进制数舍入到一定精度。我在这些类型的例子中面临困难

x = -0.000000001235 

当舍入(使用%.5f)到五位小数时会打印-0.00000

我该如何删除负号?

3 个答案:

答案 0 :(得分:2)

如果您的数字大于-0.000005,则舍入绝对值。你可以用一个简单的三元组敲打那个。

如果要将数字与小数点后第5位的容差进行比较,请使用fabs(a - b) < 0.00001作为相等的测试。我不明白你为什么要明确地对数字进行舍入,更不用说%.5f进来了。

答案 1 :(得分:1)

有两种处理问题的好方法。

您可以添加一些基本的比较代码来处理导致问题的范围:

printf("%.5f ", -0.000005 < x && x < 0.0 ? 0.0 : x);

或者您可以解释您的输出,将-0.00000替换为0.00000

但是你表达了对性能的担忧,这表明你在解决问题方面做错了。

如果打印这些值是昂贵计算的中间步骤,那么这绝对是一个坏主意,你应该编写自己的舍入函数。

如果这只是计算的结束,那么这些额外的比较或替换将对性能产生不明显的影响。

答案 2 :(得分:0)

将FP舍入到5个位置而不会产生负值-0.00000

  1. 接受最舍入的值不会是 exact ,但它将是舍入数学结果的最接近的可表示数字。

  2. 由于范围的损失,不要使用强制转换/转换为整数类型。

  3. -0.0 - &gt; 0.0

  4. 样本解决方案:

    #include <math.h>
    double round_to_5_places(double x) {
      // Only need to round finite numbers, leave infinity and not-a-numbers alone 
      if (isfinite(x)) {
        // break x into integral and fractional parts
        double ipart;
        double fpart = modf(x, &ipart);
        // Only need to round if a fractional part exist.
        // This test prevents the below `100000.0 * fpart` from overflowing.
        if (fpart) {
          // Use rint(), round(), nearbyint(), etc. depending on rounding detail needs
          x = ipart + nearbyint(100000.0 * fpart)/100000.0;
        }
        x += 0.0; // Only changes -0.0 to 0.0
      }
      return x;
    }
    

    详细信息:由于x == N.000005本身在100000.0 * fpart调用之前形成一个舍入的产品,因此nearbyint()附近的某些中间情况会绕错方向。见Double rounding。通常的解决方案是执行更高精度的乘法。