代码之家  ›  专栏  ›  技术社区  ›  pmor

如何根据当前舍入方向将float转换为int?

  •  0
  • pmor  · 技术社区  · 3 年前

    如何转换 float int 根据当前的舍入方向?

    lrint llrint 函数(C11,7.12.9.5)。但是,它们的返回值具有类型 long int long long int 。为什么没有的版本 int ?

    0 回复  |  直到 3 年前
        1
  •  2
  •   chux    3 年前

    如何转换 float int 根据当前的舍入方向?

    创建一个调用的助手函数 lrintf() 并根据C规范添加所需的错误处理:“如果四舍五入的值在返回类型的范围之外,则数字结果未指定,可能会发生域错误或范围错误。”。
    我建议不要使用 irintf() 以防稍后公布。

    #incldue <errno.h>
    #include <limits.h>
    
    int my_irintf(float x) {
      long y = lrinf(x);
      // Add desired error handling here when int/long ranges differ.
      #if LONG_MAX > INT_MAX || LONG_MIN < INT_MIN 
        // Example
        if (y > INT_MAX || y < INT_MIN) { 
          errno = ERANGE;
          y = (y > INT_MAX) ? INT_MAX : INT_MIN;
        } 
      #endif
      return (int) y;
    }
    

    某些系统 raise FE_INVALID 比如:

        if (y > INT_MAX || y < INT_MIN) { 
          fesetexcept(FE_INVALID);
          y = (y > INT_MAX) ? INT_MAX : INT_MIN;
        } 
    

    给定实现定义的功能 lrintf() 关于错误, my_irintf(float x) 每个实现都可以使用同样的条件代码。


    为什么没有的版本 int ?

    strtoi() 也存在于标准库中。我怀疑是出于类似的原因。
    看见 Why is there no strtoi in stdlib.h?

        2
  •  1
  •   0___________    3 年前

    也许是因为 int 是相当小的,您可以自己轻松地编写这样的函数。

    int irint(double x)
    {
        #if (LONG_MAX > INT_MAX && LONG_MIN < INT_MIN)
        long result = lrint(x);
        #else
        long long result = llrint(x);
        #endif
    
        if(result > INT_MAX || result < INT_MIN) 
        {
            feraiseexcept(FE_INVALID);
            return 0;
        }
        return (int)result;
    }