问题:我正在寻找一种方法将一些float
f
四舍五入到最接近的int
- 尤其是{{1}很大。从数学上讲,我想计算以下函数
其中脚本f
表示我的机器可表示的T
集合。如果是关系(例如int
).5
可以任意定义。
当前代码:低于我当前的解决方案,包括两个不满意的r(f)
示例(float
中):
main
在我#include <cmath>
#include <iostream>
#include <limits>
template <class T>
T projection(T const min, T t, T const max) {
return std::max(std::min(t, max), min);
}
template <class Out, class In>
Out repr(In in) {
using Limits = std::numeric_limits<Out>;
auto next = [](Out val) {
auto const zero = static_cast<In>(0);
return std::nexttoward(static_cast<In>(val), zero);
};
return projection(next(Limits::lowest()), std::round(in), next(Limits::max()));
};
int main() {
std::cout
<< repr<int>(std::numeric_limits<float>::max()) << " "
<< repr<int>(static_cast<float>(std::numeric_limits<int>::max())) << "\n";
}
位32
的机器上打印:
int
简短阐述:对于上限,2147483520 2147483520
计算下一个可以安全next
到float
的较小static_cast
(类似于下限)。这是必要的,因为int
中的float
示例说明:如果没有main
,next
涉及未定义的投射行为(至少)repr
为std::numeric_limits<int>::max() + 1
} float
,此数字无法表示。
我int
的明显缺点是它在数学意义上是不正确的:对于大repr
s(例如。float
),它不会返回std::numeric_limits<float>::max()
问题:
这是否有一种更简单的方法来解决问题(从简化手动数字运算的角度来看更容易,更多地委托给std::numeric_limits<int>::max()
- 函数)?
如何std
仅使用完全定义的行为(在数学意义上)是正确的(没有未定义且没有实现定义的行为)?
到目前为止,我一直在谈论repr
和int
,但(已经建议的模板)这应该只是一个开始。组合怎么样
float
和double
或long
和double
?