C++ 将大浮点舍入为整数

C++ 将大浮点舍入为整数,c++,C++,问题:我正在寻找一种方法,将一些floatf四舍五入到最接近的int,尤其是当f很大时。从数学上讲,我想计算以下函数 其中scriptT表示可由我的机器表示的ints集合。如果系结(例如.5)r(f)可以任意定义 当前代码:下面是我当前的解决方案,包括两个不满意的float示例(在main中): 简短细化:对于上界,next计算下一个较小的float,可以安全地static\u cast转换为int(与下界类似)。这是必要的,因为main中的我的float示例演示了:在没有next的情况下,

问题:我正在寻找一种方法,将一些
float
f
四舍五入到最接近的
int
,尤其是当
f
很大时。从数学上讲,我想计算以下函数

其中script
T
表示可由我的机器表示的
int
s集合。如果系结(例如
.5
r(f)
可以任意定义


当前代码:下面是我当前的解决方案,包括两个不满意的float示例(在main中):

简短细化:对于上界,
next
计算下一个较小的
float
,可以安全地
static\u cast
转换为
int
(与下界类似)。这是必要的,因为
main
中的我的
float
示例演示了:在没有
next
的情况下,
repr
涉及到未定义的强制转换行为(至少)
std::numeric\u limits::max()+1
作为
float
int
,其中该数字不可表示

我的
repr
的明显缺点是它在数学意义上是不正确的:对于大的
float
s(例如
std::numeric\u limits::max()
),它不会返回
std::numeric\u limits::max()


问题:

  • 这是否有一种更简单的方法来解决问题(更简单的意思是更少的手动数字处理和更多地委托给
    std
    -功能)

  • 只有完全定义的行为(没有未定义的行为,也没有实现定义的行为),如何才能使
    repr
    正确(在数学意义上)

  • 到目前为止,我一直在谈论
    int
    float
    ,但是(正如模板已经建议的那样),这应该只是一个开始。组合呢

    • double
      long
    • double
      long

  • 那使用什么呢?它有什么微妙的问题吗?或者你不知道它的存在吗?
    std::round
    返回
    float
    ,我需要返回值
    int
    。不,如果你使用(5)到(12)个表单(
    lround
    llround
    ),它们返回一个整数。不适用于例如
    std::numeric\u limits::max()
    还是我遗漏了什么?如果您关心的是健壮性,请将其放入双精度,加上0.5,然后发言。然后针对您使用的整数类型,检查INT_MAX/MIN或等效值。
    #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";
    }
    
    2147483520 2147483520