【问题标题】:Where is Round() in C++? [duplicate]C++ 中的 Round() 在哪里? [复制]
【发布时间】:2009-02-16 19:01:57
【问题描述】:

重复:round() for float in C++


我正在使用 VS2008 并且我已经包含了 math.h 但我仍然找不到一个圆形函数。存在吗?

我在 google 上看到一堆“添加 0.5 并转换为 int”的解决方案。这是最佳做法吗?

【问题讨论】:

  • 加 0.5 并强制转换为 int 对负数不起作用。演员截断(所以它舍入 -4.5 到 -4)。因此,尝试使用此方法舍入 -5.0 将为您提供 -4 的输出。用 ceil() 替换演员表,它应该可以工作。但是,是的,您必须自己实现,或者在 3rd 方库中找到它。
  • 呃,当然,假设我在上面写了 floor() 。要使用 ceil,您必须减去 0.5
  • @jalf 正如我在my answer to the dup 中指出的那样,滚动你自己的有很多问题,今天即使你坚持使用 C++03 提升也会是一个比尝试自己推出更好的建议。

标签: c++ rounding


【解决方案1】:

你可以使用 C++11 的std::round()

如果您仍然坚持旧标准,您可以使用std::floor(),它总是四舍五入到较小的数字,以及std::ceil(),它总是四舍五入到较大的数字。

要获得正常的舍入行为,您确实可以使用floor(i + 0.5)

这种方式会给您带来负数问题,解决该问题的方法是使用 ceil() 处理负数:

double round(double number)
{
    return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5);
}

另一种更简洁但更耗费资源的方法是使用字符串流和输入/输出操纵器:

#include <iostream>
#include <sstream>

double round(double val, int precision)
{
    std::stringstream s;
    s << std::setprecision(precision) << std::setiosflags(std::ios_base::fixed) << val;
    s >> val;
    return val;
}

仅当您的资源不低和/或需要控制精度时才使用第二种方法。

【讨论】:

  • 您认为将字符串转换为字符串并返回更更干净
  • 是的,使用 +0.5 技术会遇到负数问题,而且您也无法控制精度。
  • 只要您使用 floor(),+0.5 应该可以正常工作。无论如何,这就变成了一个正确性的问题,而不是哪个更干净。
  • 还需要包含 (使用 MSVC 2012)才能使用轮函数。
  • 我更喜欢copysignf(floorf(fabs(x) + 0.5f), x),因为它是无分支的,并且模拟分支的代码实际上是 bin-ops(abs -> &amp;~0x80000000,copysign 是位传输等)
【解决方案2】:

使用floor(num + 0.5) 不适用于负数。在这种情况下,您需要使用ceil(num - 0.5)

double roundToNearest(double num) {
    return (num > 0.0) ? floor(num + 0.5) : ceil(num - 0.5);
}

【讨论】:

    【解决方案3】:

    Microsoft math.h 中实际上没有圆形函数。
    但是,您可以改用静态方法 Math::Round()。
    (取决于您的项目类型。)

    【讨论】:

    • Visual Studio 现在支持圆形 see my comment here 也可以查看我的 answer 了解我认为在您无法使用更现代的编译器的情况下的全套替代方案。
    【解决方案4】:

    我不知道这是否是最佳实践,但使用 0.5 技术和 floor() 似乎是要走的路。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 1970-01-01
      • 1970-01-01
      • 2017-07-23
      • 2014-12-27
      相关资源
      最近更新 更多