什么规则控制将static_cast<float>应用于双精度的舍入行为?

如果我们在 C++ 中有一个双精度值并对其进行 astatic_cast<float>处理,返回值的绝对值是否总是较小?我的直觉在这背后说是的,原因如下。

  • 可能的单精度指数集严格是双精度指数的子集
  • 在将双精度尾数转换为单精度时,位可能会被截断然后结束以使双精度尾数适合浮点数尾数。但是,如果四舍五入更准确,有时会将其向上舍入到下一个最高浮点值并非不可能。也许这取决于系统,或者在某些标准中定义。

我在以下程序中对此进行了一些数值实验。似乎有时会发生向上取整,而其他时候则向下取整。

在哪里可以找到有关如何期望此舍入行为的更多信息?它是否总是四舍五入到最近的浮点数?

#include <cmath>
#include <iostream>

int main() {
  // Start testing double precision values starting at x, going up to max
  double x = 0.98;
  constexpr double max = 1e10;

  // Loop over many possible double-precision values, print out
  // if casting to float ever produced a larger number.
  int output_counter = 0; // output every n steps
  constexpr int output_interval = 100000000;

  std::cout.precision(17);
  while (x < max) {
    // volatile to ensure compiler doesn't optimize this out
    volatile float xprime = static_cast<float>(x);
    double xprimeprime = static_cast<double>(xprime);

    if (xprimeprime > x)
      std::cout << "Found a round up! x=" << x << ", xprime = "<< xprime << std::endl;

    // Go to the next higher double precision value
    x = std::nextafter(x, std::numeric_limits<double>::infinity());

    output_counter++;
    if (output_counter == output_interval) {
      std::cout << x << std::endl;
      output_counter = 0;
    }
  }
}

回答

标准在[conv.double] 中说:

浮点类型的纯右值可以转换为另一种浮点类型的纯右值。如果源值可以在目标类型中精确表示,则转换的结果就是该精确表示。如果源值介于两个相邻的目标值之间,则转换的结果是这些值中任何一个的实现定义选择。否则,行为是未定义的。

请注意,使用<limits>标题,您可以通过std::numeric_limits<T>::round_style. 有关可能的值,请参阅[round.style]。(至少我假设浮点转换属于浮点运算。)


以上是什么规则控制将static_cast&lt;float&gt;应用于双精度的舍入行为?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>