我正在构建一个具有极坐标系和笛卡尔坐标系以及 3d 坐标系的世界。我的坐标都是用 float 表示的。我开始编写测试,然后从那里编写代码。一切都很好,直到我开始测试精确值,然后我开始遇到问题。
这是一个示例测试:
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 的精度输出。对于 float 14.142136,我得到:
- 5 = 14.1421404
- 4 = 14.1421003
- 3 = 14.1420002
- 2 = 14.1400003
- 1 = 14.1000004
- 0 = 14.0000000
这根本不是我所期待的!我希望位数会随着精度的降低而减少,并适当向上或向下舍入。像这样:
- 5 = 14.14214
- 4 = 14.1421
- 3 = 14.142
- 2 = 14.14
- 1 = 14.1
- 0 = 14.0
显然我在这里做错了什么,有人对我有个好主意吗?
最佳答案
你方的多重误解:
- 设置精度仅适用于将浮点渲染到
缓冲区
的方式。不是您将其转换回的float
。 - 当转换回
float
时,您会再次遇到舍入错误。 - 您实际上想做的是检查两个数字是否在彼此的一定偏差范围内。这与四舍五入无关。
关于c++ - 在 Visual C++ 中,如何将浮点值舍入到指定的精度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48974749/