如何将一个数字限制在一个范围内

4

我有一个函数,用于将旋转角度限制在0.0到360.0的范围内:

private float ClampRotation( float rotation ) {

    while( rotation < 0.0f ) rotation += 360.0f;
    while( rotation >= 360.0f ) rotation -= 360.0f;

    return rotation;

}

这个函数的效果很好,也可能没有更有效率的方式了,但我想知道是否有原生的Java函数能够实现同样的功能?

最接近的是Math.min/max,但它不能像这样工作。旋转-10.0应该输出350.0而不是min/max会输出的0.0。


这肯定不是最有效的解决方案 - 数字越大,循环时间就越长。 - tdammers
“不能更有效率了” 对于旋转值较大的情况,正如@Paul的回答所证明的那样,它可以极大地提高效率。 - President James K. Polk
4个回答

5

% (取模) 适用于浮点数,因此请使用 rotation % 360.0f(对于负数,您需要在后面添加 360.0)


取模运算符只是检查两个数字是否可以被整除...我不确定它如何帮助 OP 的问题。 - William Linton
4
实际上,它返回一个数被另一个数除后的“余数”,当余数为零时,它们是完全可除的。 - SimonJ

4

使用取模运算符,考虑小于0的值;

private float ClampRotation( float rotation ) {

    rotation = rotation % 360f;

    if (rotation < 0f) rotation += 360f;

    return rotation;

}

3

这只是数学问题...你可以这样做:

private float ClampRotation( float rotation ) {

    return rotation+360.0f*Math.ceil(-rotation/360.0f);

}

我相信这没问题。


2
我认为你刚刚发明了“%”运算符 ;) - SimonJ
实际上是相反的(查找“旋转”在360中出现的次数。模运算找到余数) (顺便说一句 - 当你说可以用%代替时,你仍然是正确的。由于某种原因,我更喜欢这个..) - RoeeK
不,这是“向下取整除法”模运算的一种变体(请参见http://en.wikipedia.org/wiki/Modulo_operation)。它没有问题-它对Knuth有效! - SimonJ

1

您有传统的实现方式,可以将小于一个数量级之内的角度包装到所需范围内。

对于浮点数,模数有点奇怪 - 对于负数它返回负数,因此仍然需要一个分支,并且涉及除法,这在某些机器上速度较慢(例如我还没有找到一台机器,在那里%比用几次减法绕过循环要便宜得多)。

如果您的值在-1000到+1000范围内,则您的版本既更清晰又更快。如果您的值超出此范围,请选择基于模数的版本。如果非常重要,请使用您要使用的值范围在您的硬件上测试两者。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接