C - ceil/float 舍入到 int 保证

C - ceil/float rounding to int guarantees

提问人:Tom Hickson 提问时间:5/12/2022 更新时间:5/12/2022 访问量:79

问:

我想知道是否有任何情况下,由于浮点不准确,这样的代码会不正确:

#include <math.h>

// other code ...

float f = /* random but not NAN or INF */;

int i = (int)floorf(f);

// OR

int i = (int)ceilf(f);

这些值有什么保证吗?如果我有一个格式良好的(不是 NAN 或 INF)将始终是它四舍五入的整数,无论哪种方式。fi

我可以想象这样一种情况:(使用糟糕的规范/实现)您得到的值是略低于真实值的值,而不是略高于/等于,但实际上更接近。然后,当您截断时,它实际上会向下舍入到下一个较低的值。

在我看来,这似乎是不可能的,因为整数可以是 ieee754 浮点数中的精确值,但我不知道是否保证是该标准float

c 浮动精度

评论

1赞 Bart Friederichs 5/12/2022
float不能保证IEEE754,但在大多数系统上,可以。所以这个问题是非常理论化的。
0赞 Eugene Sh. 5/12/2022
你的意思是,如果四舍五入到一个整数,会发生什么,不能表示为?这可能发生,这很有趣。ffloat
0赞 Garr Godfrey 5/12/2022
我的意思是,浮点值可能超出 int 的范围,例如 1E38。尝试将 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000int
0赞 Eugene Sh. 5/12/2022
@GarrGodfrey 将实数值转换为整数的行为,其整数部分无法在目标类型中表示,这是未定义的。port70.net/~nsz/c/c11/n1570.html#6.3.1.4p1
1赞 Eric Postpischil 5/12/2022
@EugeneSh.: 定义为 .它不能舍入为不能表示为 .如果你的意思是 ,那么 C 标准对浮点格式的规范保证了任何有限度的 在 中是可表示的;它可以通过将浮点表示中的数字设置为零来表示。 出于更复杂的原因,也总是可表示的,除非它溢出到∞。ffloatfloatfloorf(f)floorfloatfloatfceilf(f)

答:

4赞 Eric Postpischil 5/12/2022 #1

C 标准在指定浮点行为方面很草率,因此在技术上没有完全指定生成正确的下限或生成正确的上限。floorf(f)fceilf(f)f

尽管如此,据我所知,没有 C 实现会出错。

如果 ,而不是 ,则有 C 实现可能会以不同的方式计算表达式,这些实现不会得到与始终使用 IEEE-754 算术相同的结果。floorf(some variable)floorf(some expression)

如果 C 实现定义 ,它应该使用 IEEE-754 算术计算表达式。__STDC_IEC_559__

尽管如此,如果 的地板超出 的范围,当然不能保证设置为 的地板。int i = (int)floorf(f);iffint

评论

0赞 Tom Hickson 5/13/2022
谢谢,这就是我一直在找的。我只是不希望它采用像 3.999f 这样的东西,然后将其下放到 2.9999999999999f,然后将其截断为 2 种东西。因此,只要我不使用一些晦涩难懂的架构或编译器,这不应该发生吗?