具有环绕溢出的浮点约束函数的最简洁实现
我正在寻找以下函数的最简洁和通用的实现:
float Constrain(float value, float min, float max);
Constrain() 将 value
限制在 [min, float)
范围内。即,范围包括 min 但不包括 max
和大于 max
或小于 min
的 values
环绕在一个圆圈。即,以与整数上溢/下溢类似的方式。
该函数应通过以下测试:
Constrain( 0.0, 0.0, 10.0) == 0.0
Constrain( 10.0, 0.0, 10.0) == 0.0
Constrain( 5.0, 0.0, 10.0) == 5.0
Constrain( 15.0, 0.0, 10.0) == 5.0
Constrain( -1.0, 0.0, 10.0) == 9.0
Constrain(-15.0, 0.0, 10.0) == 5.0
Constrain( 0.0, -5.0, 5.0) == 0.0
Constrain( 5.0, -5.0, 5.0) == -5.0
Constrain( 0.0, -5.0, 5.0) == 0.0
Constrain( 10.0, -5.0, 5.0) == 0.0
Constrain( -6.0, -5.0, 5.0) == 4.0
Constrain(-10.0, -5.0, 5.0) == 0.0
Constrain( 24.0, -5.0, 5.0) == 4.0
Constrain( 0.0, -5.0, 0.0) == -5.0
Constrain( 5.0, -5.0, 0.0) == -5.0
Constrain( 10.0, -5.0, 0.0) == -5.0
Constrain( -3.0, -5.0, 0.0) == -3.0
Constrain( -6.0, -5.0, 0.0) == -1.0
Constrain(-10.0, -5.0, 0.0) == -5.0
请注意,可以假定 min
参数在数值上始终小于 max
。
可能有一个非常简单的公式可以解决这个问题,但是我非常愚蠢,不知道它的通用解决方案。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您几乎正在寻找
fmod
函数。fmod(x,y)
返回x
除以y
的余数,两者均为double
。结果的符号与x
相同(相当于,相应的整数部分函数是向零舍入的函数),这就是为什么它只是几乎你想要什么。因此,如果x>=lo
则lo+fmod(x-lo,hi-lo)
是正确的,但如果x > 那么
hi+fmod(x-lo,hi-lo)
几乎是正确的事情,除了当x 时,结果可能是 < code>lo
或hi
您会得到hi
而不是lo
。所以。您可以分为三种方式:
或者您可以使用
floor
代替 [已编辑,因为第一个版本根本不是我的意思]:如果您关心的是可理解性,请选择;如果您关心的是性能,请尝试两者。
You're almost looking for the
fmod
function.fmod(x,y)
returns the remainder on dividingx
byy
, both beingdouble
s. The sign of the result is the same as that ofx
(equivalently, the corresponding integer-part function is the one that rounds towards zero), and that's why it's only almost what you want. So, ifx>=lo
thenlo+fmod(x-lo,hi-lo)
is the Right Thing, but ifx<lo
thenhi+fmod(x-lo,hi-lo)
is oh-so-nearly the Right Thing except that whenx<lo
and the result could be eitherlo
orhi
you gethi
instead oflo
.So. You can split three ways:
or you can use
floor
instead [EDITED because the first version of this wasn't what I meant at all]:Take your pick if what you care about is comprehensibility; try them both if what you care about is performance.
lrint() 可能会更快。
lrint() may be faster.
lrint() 可能会更快。
lrint() may be faster.
这也有效:
This also works: