c - 将 37.1-28.75 浮点计算正确舍入为 8.4 而不是 8.3

标签 c floating-point rounding

我在浮点舍入方面遇到问题。我想计算 float 并将其四舍五入为(给定)N 位小数。在此示例中,我想四舍五入到小数点后 1 位。

计算 37.1-28.75 将得出 float 8.349998(而不是 8.35),这将导致 printf 四舍五入到 8.3,而不是小数点后 1 位的 8.4。

数学上的实际结果是 37.10-28.75=8.35000000,但由于浮点不精确,它被转换为 8.349998,然后在使用 1 位小数舍入时转换为 8.3,而不是 8.4。

最小可重现示例:

float a = 37.10;
float b = 28.75;
//a-b = 8.35 = 8.4
printf("%.1f\n", a - b); //outputs 8.3 instead of 8.4

在结果中添加以下内容是否有效:

float result = a - b;

if (result > 0.0f)
{
    result += powf(10, -nr_of_decimals - 1) / 2;
}
else
{
    result -= powf(10, -nr_of_decimals - 1) / 2;
}

编辑:更正了我想要 1 位小数舍入输出,而不是 2 位小数

编辑2:还需要负面结果(28.75-37.1 = -8.4)

最佳答案

在我的系统上,我实际上得到了8.35。您可能必须首先将舍入方向设置为“最近”,尝试此操作(使用例如 gcc ... -lm 进行编译):

#include <fenv.h>
#include <stdio.h>

int main()
{
  float a = 37.10;
  float b = 28.75;
  float res = a - b;

  fesetround(FE_TONEAREST);

  printf("%.2f\n", res);
}

关于c - 将 37.1-28.75 浮点计算正确舍入为 8.4 而不是 8.3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64981966/

相关文章:

c - 尝试验证换行符存在后,换行符删除不起作用

c - 从c中的字符串中提取double

python - Numpy 的 float32 和 float 比较

linux - 是否可以在 ifort 中启用舍入为零或舍入为负无穷大?

在 C 中构建函数调用

c++ - C 读取文件时出错

c++ - 浮点运算,C 输出

c# - 十进制值舍入 .99

c# - 将十进制货币值四舍五入为便士倍数

c - Linux 中的启动默认堆大小?