我经常使用范围为 [0,1] 的 float
或 double
类型。我知道浮点数运算是不精确的,所以在进行操作之前/之后,我通常会将我的值夹紧(clamp)到这个范围内,以确保它们处于此范围。
在某些情况下,我依赖于浮点数不会稍微偏向负数,并且恰好等于 <= 1
,因此这一步是必要的。
例如,在以下任何一个函数中,这都是必要的:
// x and y are guaranteed to be in [0, 1]
float avg(float x, float y) {
// the average of [0, 1] values should always be in [0, 1]
return std::clamp<float>((x + y) / 2, 0, 1);
}
float mul(float x, float y) {
// the product of [0, 1] values should always be in [0, 1]
return std::clamp<float>(x * y, 0, 1);
}
float pow(float x, unsigned y) {
// raising an [0, 1] value to any unsigned power should also result in an [0, 1] value
return std::clamp<float>(std::pow(x, y), 0, 1);
}
当浮点数进行算术运算超出 [0, 1] 范围时,有哪些一致的规则吗?
avg
函数一样。+肯定会超出范围,但/会将其带回。 - Goswin von Brederlowsqrt
和我认为cbrt
也进入了IEEE754的特殊函数列表。 - Bathsheba