【问题标题】:How to round a double to an int using Banker's Rounding in C如何使用 C 中的银行家四舍五入将 double 舍入为 int
【发布时间】:2024-01-02 07:25:01
【问题描述】:

我想编写一个函数来使用银行家的舍入方法将双精度数舍入为整数(将一半舍入为偶数:http://en.wikipedia.org/wiki/Rounding#Round_half_to_even),例如:

int RoundToInt(double x);

我该怎么做?

更新

我能得到的最好的是:

int RoundToInt(double x)
{
  int s = (int)x;
  double t = fabs(x - s);

  if ((t < 0.5) || (t == 0.5 && s % 2 == 0))
  {
    return s;
  }
  else
  {
    if (x < 0)
    {
      return s - 1;
    }
    else
    {
      return s + 1;
    }
  }
}

但这很慢,我什至不确定它是否准确。

有没有一些快速准确的方法来做到这一点。

【问题讨论】:

  • @AdamCasey 我需要解决这个问题,但我没有解决它,所以我找他帮忙。还是我的问题真的很愚蠢?
  • 您的需求和问题不是问题。检查我评论中的链接;你需要证明你是一个。投入一些精力去研究这个问题,B.尝试自己编写一些代码,然后 c.尝试在您的代码失败时对其进行调试
  • @AdamCasey 我已经完成了我的研究,但我认为它没有帮助。我的代码又慢又笨拙,我不知道它是否准确。这是我能做的最好的了。
  • 这就是一个好问题现在的样子。我将反对票改为赞成票!

标签: c algorithm rounding


【解决方案1】:

使用标准的lrint函数;在默认的舍入模式下,它会给出你想要的结果。

【讨论】:

  • 你确定吗?您链接到的手册页没有提到当数字恰好在两个整数之间时会发生什么。
  • lrint 遵循当前的舍入模式。默认舍入模式是最近舍入,也称为舍入到偶数或“银行家”舍入。
  • 我用的是VC++,不支持lrint
  • 是否支持rint?使用rint 然后将结果转换为整数类型(或让它通过赋值隐式转换)应该也可以工作。
  • 不行,VC++好像只支持C90标准。
【解决方案2】:
double decimal = x % 1;
if(decimal < 0.5) return (int)x;
if(decimal > 0.5) return (int)x + 1;
return (int)x + ((int)x % 2 == 1 ? 1 : 0);

【讨论】:

  • 我认为这不能正常工作。您允许累积误差改变您的舍入方法,这是不正确的。例如round(5.0 / 2.0)必须使用2.5 的舍入规则。但是如果你的 round 函数看到 2.4999999993 (由于除法中的四舍五入),它将使用错误的规则。
  • @DavidSchwartz:你为什么声称它应该这样工作?我看不出做出这种判断的依据。
  • 这是银行家四舍五入的定义。 “完美的一半四舍五入到最接近的偶数。”如果您不能确保将 7/2 舍入到 4,则不是银行家的舍入。
  • 我说的是您声称它应该将 2.4999999993 视为 2.5;我认为没有任何根据。此外,您声称 5.0/2.0 可能是 2.4999999993 是无稽之谈; 5.0/2.0 总是准确的。
  • 双舍入不是解决问题的办法;对于它“修复”的每一种情况,都有同样多的情况会导致错误方向的舍入。这个故事的寓意是浮点永远不是一种有效的货币格式。
最近更新 更多