在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么

What is the best way to round large unsigned floating point numbers to integers in C++?

本文关键字:四舍五入 整数 最佳 是什么 方法 浮点数 无符号 C++      更新时间:2023-10-16

我需要用标准";math.h";中点舍入行为。其中一些数字具有以下特性:

  • 大于LLONG_MAX
  • 小于或等于ULLONG_MAX

我注意到标准库舍入函数没有"unsigned"版本。此外,我怀疑当中间双数值太大而无法放入尾数时,人们用来做这件事的一些技巧就不再有效了。

进行此转换的最佳方法是什么?

我会使用std::round,然后箝位到uint64范围。此外,您还需要决定如何处理NaN。

std::round不转换为整数。请注意,在C&C++正在截断并且未定义超出范围的值。

CCD_ 3实现了标准";学校;键入四舍五入到最近的整数,其中中点情况向外四舍五舍五入(例如round(1.5) == 2; round(-1.5) = -2(。

当前的取整模式被忽略,这也不是IEEE754取整到最近的。后者将使用round half to even并上下舍入平局打破情况,以减少统计偏差。

对于long long,可以这样做。

double iv = std::round(val);
if (std::isnan(iv)) {
return 0LL;
} else if (iv > LLONG_MAX)
return LLONG_MAX;    
} else if (iv < LLONG_MIN) {
return LLONG_MIN;
} else {
return (long long)iv;
}

unsigned long long的情况是相应的。

double iv = std::round(val);
if (std::isnan(iv)) {
return 0ULL;
} else if (iv > ULLONG_MAX)   // ok, if you know your values are less this can be spared of course
return ULLONG_MAX;    
} else if (iv < 0) {
return 0ULL;
} else {
return (unsigned long long)iv;
}

最简单的四舍五入方法是强制转换为目标类型:
想象一下,你想将2.3舍入为整数根,然后执行:

return (int) 2.3;

所以,一般来说,你会这样做:

return (destination_type) x;

然而,这里有一个问题,你总是四舍五入,正如你在这个2.7的例子中看到的那样:

return (int) 2.7;
=> yields 2

如果你想四舍五入到最接近的值,你需要加0.5,然后四舍五进:

return (int) (2.7 + 0.5);
=> yields 3

因此,当你想使用最接近的舍入来舍入到任何目的地类型时,你需要:

return (destination_type) (x + 0.5);