将浮点值的std :: vector传递给函数会稍微改变一下值

时间:2017-06-29 07:28:24

标签: c++ c++11 vector

我有一个非常简单的小函数,可以验证传递的vector中的值:

bool Verify( std::vector<std::pair<float, float>> const & source) {
    // The lookup table must be changing linearly on input
    float delta_x{};
    for (unsigned i = 1; i < source.size(); i++) {
        auto input_delta = std::abs(source[i].first - source[i-1].first);
        if (i == 1) {
            delta_x = input_delta;
        } else {
            std::cout << "LUT"
              << "Expected step: '" << std::setprecision(10) << delta_x << "'."
              << " measured step[" << i << "]: '"
              << std::setprecision(10) << input_delta << "'"
              << (input_delta-delta_x)
              << ":" << source[i].first << "-" << source[i-1].first << std::endl;
        if (delta_x != input_delta) {
            return false;
        }
     }
  }

  return true;
}

看起来相当简单。但是,它失败了。当我传递这样一个简单的向量时:

    std::vector<std::pair<float, float>>kDecodeLut{
  {  -1.326, 101.3974},
  {   6.174, 96.0049 },
  {  13.674, 91.5644 },
  {  21.174, 87.5549 },
  {  28.674, 83.7873 },
  {  36.174, 80.1683 },
  {  43.674, 76.6441 },
  {  51.174, 73.1802 },
  {  58.674, 69.7524 }};

Verify方法看到的值与向量中的值不完全相同。这是打印输出:

LUTExpected step: '7.5'. measured step[2]: '7.5'0:13.67399979-6.173999786
LUTExpected step: '7.5'. measured step[3]: '7.5'0:21.17399979-13.67399979
LUTExpected step: '7.5'. measured step[4]: '7.5'0:28.67399979-21.17399979
LUTExpected step: '7.5'. measured step[5]: '7.5'0:36.17399979-28.67399979
LUTExpected step: '7.5'. measured step[6]: '7.5'0:43.67399979-36.17399979
LUTExpected step: '7.5'. measured step[7]: '7.5'0:51.17399979-43.67399979
LUTExpected step: '7.5'. measured step[8]: '7.5'0:58.67399979-51.17399979

好像从原始kDecodeLut向量到Verify内的内部变量有一些数字转换。

真的有某种转换吗?我不打算以任何形式复制或修改kDecodeLut向量。 还有什么可以解释这种行为?

修改: 我已添加代码以在调用Verify之前打印值,并且它们会按预期显示出来。

 for (unsigned i = 1; i < kTiltWingDecodeLut.size(); i++) {
  std::cout << "LUT"
            << ":" << kTiltWingDecodeLut[i].first << "-" << kTiltWingDecodeLut[i-1].first << std::endl;
}
Verify(kTiltWingDecodeLut);

这是输出

LUT:6.174--1.326
LUT:13.674-6.174
LUT:21.174-13.674
LUT:28.674-21.174
LUT:36.174-28.674
LUT:43.674-36.174
LUT:51.174-43.674
LUT:58.674-51.174
LUTExpected step: '7.5'. measured step[2]: '7.5'0:13.67399979-6.173999786
LUTExpected step: '7.5'. measured step[3]: '7.5'0:21.17399979-13.67399979
LUTExpected step: '7.5'. measured step[4]: '7.5'0:28.67399979-21.17399979
LUTExpected step: '7.5'. measured step[5]: '7.5'0:36.17399979-28.67399979
LUTExpected step: '7.5'. measured step[6]: '7.5'0:43.67399979-36.17399979
LUTExpected step: '7.5'. measured step[7]: '7.5'0:51.17399979-43.67399979
LUTExpected step: '7.5'. measured step[8]: '7.5'0:58.67399979-51.17399979

1 个答案:

答案 0 :(得分:2)

这是四舍五入的情况。正如您在this page,6.174上看到的,转换为32位浮点时更像是6.1739998。实际表示在该页面上解释:2 ^ 2 * 1.5434999(1.10001011001000101101000二进制).64位浮点值使用乘法器中的附加二进制位01110010101100000010000011001比特价值。

如果您使用相同的setprecision(10)打印之前的值,您会看到相同的数字。