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

How to convert float to int according to the current rounding direction?

提问人:pmor 提问时间:8/4/2023 更新时间:8/8/2023 访问量:80

问:

如何根据当前的舍入方向转换为?floatint

有 and 函数(C11、7.12.9.5)。但是,它们的返回值具有 types 和 .为什么没有版本?lrintllrintlong intlong long intint

C 异常 浮点 类型转换 舍入

评论

0赞 Adrian Mole 8/4/2023
另外,请注意,C 标准仅保证 an 至少为 16 位,因此从 32 位浮点类型转换可能被认为(由定义函数的委员会)过于狡猾。A 保证至少为 32 位,IIRC、intxrint()long int
0赞 pmor 8/4/2023
@AdrianMole 回复:“简单投射”:考虑.超出范围。因此,本机转换为 预计会提高 .但是,不会提出.lrintf((long)INT_MAX+130)(long)INT_MAX+130intintFE_INVALIDint i = (int)lrint(f);FE_INVALID
0赞 0___________ 8/4/2023
@AdrianMole UB(int)lrint(f)
1赞 pmor 8/7/2023
@chux-ReinstateMonica 最初我用.然后,在比较从 ARM 指令(以及其他舍入模式的类似指令)获得的结果时,我注意到可能缺少 Invalid FP 异常。因此,我想知道为什么没有并问了这个问题。在等待答案时,我自己写了(它调用,然后检查结果是否在范围内;如果不是,它会引发无效的 FP 异常并返回 0)。lrintffcvtzsirintfirintflrintfINT_MIN..INT_MAX
1赞 chux - Reinstate Monica 8/8/2023
@pmor 为了清楚起见,我的意思是“你为什么用来转换而不是”,显然你是这样正确地接受了评论。lrint()floatlrintf()

答:

1赞 0___________ 8/4/2023 #1

也许是因为它很小,你可以很容易地自己编写这样的函数。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;
}
2赞 chux - Reinstate Monica 8/8/2023 #2

如何根据当前的舍入方向转换为?floatint

创建一个帮助程序函数,该函数根据 C 规范调用并添加所需的错误处理:“如果舍入值超出返回类型的范围,则未指定数值结果,并且可能会发生域错误或范围错误。
我建议不要使用,以防以后出现。
lrintf()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;
}

一些系统会引发以下FE_INVALID

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

给定实现定义的功能,并带有 on 错误,每个实现都可以使用类似的条件代码。lrintf()my_irintf(float x)


为什么没有版本?int

标准库中也不存在。我怀疑出于类似的原因。
请参阅为什么 stdlib.h 中没有 strtoi?
strtoi()

评论

0赞 pmor 8/8/2023
没有,但是,例如,有.strtoiatoi