在 Visual C++ 中,如何将浮点值舍入到指定的精度?

In Visual C++ how can I round float values to a specified precision?

我正在构建一个具有极坐标系和笛卡尔坐标系以及 3d 坐标系的世界。我的坐标都是用浮点数表示的。我开始编写测试,然后从那里编码。一切都很好,直到我开始测试精确值,然后我开始遇到问题。

这是一个示例测试:

TEST_METHOD(TestAngleFromPointUsingRelativeCoordsQuandrant1_1)
{
   // ARRANGE
   TwoDCoordinate testPoint = TwoDCoordinate(10, 10);
   PolarCoordinate expected = PolarCoordinate(45.0F, 14.142136F);

   // ACT
   PolarCoordinate actual = CoordinateConverter::ConvertFrom2DToPolar(testPoint);
   TwoDCoordinate convertedCoord = CoordinateConverter::ConvertFromPolarTo2D(actual, TwoDCoordinate(0.0F, 0.0F));

   // ASSERT
   ActAndAssertOnConversion(expected, actual);
}

值 14.142136 对我来说有点太精确了,14.142 就可以了。所以我去研究了更多的std方法并发现了std::stof。基于此我写了这个函数:

float BaseTester::RoundFloatTo(float fnum, int round_digits)
{
     std::string::size_type sz;
     std::ostringstream oss;
     oss << std::fixed << std::showpoint;
     oss << std::setprecision(round_digits);
     oss << fnum;
     std::string buffer = oss.str();
     return std::stof(buffer, &sz);
}

我以为我的麻烦已经过去了,直到我查看了精度从 5 到 0 的输出。对于浮点数 14.142136,我得到了:

  1. 5 = 14.1421404
  2. 4 = 14.1421003
  3. 3 = 14.1420002
  4. 2 = 14.1400003
  5. 1 = 14.1000004
  6. 0 = 14.0000000

这完全不是我所期待的!我希望位数会随着精度的降低而减少,并适当地向上或向下舍入。像这样:

  1. 5 = 14.14214
  2. 4 = 14.1421
  3. 3 = 14.142
  4. 2 = 14.14
  5. 1 = 14.1
  6. 0 = 14.0

显然我在这里做错了什么,有人对我有好主意吗?

你这边的多重误会:

  • 设置精度仅适用于将浮点数呈现为 buffer 的方式。不是你要将其投回的 float
  • 当转换回 float 时,您会再次出现舍入错误。
  • 您实际要做的是检查两个数字是否在彼此的某个偏差范围内。这与四舍五入无关。