Java:在忽略符号的情况下执行数学运算

Java:在忽略符号的情况下执行数学运算,java,math,integer,bit-manipulation,sign,Java,Math,Integer,Bit Manipulation,Sign,我想做一个游戏,包括计算执行一些简单数学运算所需的力。我有一个dx变量,表示沿X轴的速度和方向。现在我想减去摩擦力,但如果dx的方向是负的,它必须是一个加法。在返回有符号值时,是否有任何方法可以使用绝对值从dx中减去摩擦力?我在寻找位运算符,但我不知道有什么可能性 我能做的(我想): 最安全的选择是使用条件。你不希望分数改变方向 dx = dx < -friction ? dx + friction : dx > friction ? dx - friction : 0 dx=dx

我想做一个游戏,包括计算执行一些简单数学运算所需的力。我有一个
dx
变量,表示沿X轴的速度和方向。现在我想减去摩擦力,但如果
dx
的方向是负的,它必须是一个加法。在返回有符号值时,是否有任何方法可以使用绝对值从
dx
中减去摩擦力?我在寻找位运算符,但我不知道有什么可能性

我能做的(我想):


最安全的选择是使用条件。你不希望分数改变方向

dx = dx < -friction ? dx + friction : dx > friction ? dx - friction : 0
dx=dx<-摩擦力?dx+摩擦力:dx>摩擦力?dx-摩擦力:0

您的代码不正确,原因有两个:

  • dx=(dx>1;
    不会消除符号。此外,它可能会错误地产生“假阳性”(即假负数)当位31设置为
    1
    时,即使将
    >>
    替换为
    >>
    也不会得到绝对值,因为
    int
    存储在两个补码中,而不是作为符号+值表示
  • sign
    将是二进制表示形式的
    10000…00
    00000…00
    ,因此
    (dx-摩擦)&sign
    不会将符号与其他计算结果合并
您可以使用函数更改加减,如下所示:

dx -= Integer.signum(dx) * friction;

用显而易见的方式去做:除非有性能问题,否则不要试图变得聪明

if(dx >0 ) {
    dx -= friction;
} else {
    dx += friction;
}
如果这看起来有点冗长,请将其隐藏在方法中:

dx = applyFriction(dx,friction);

int applyFriction(int pos, int friction) {
     if(pos > 0) {
           return pos - friction;
     } else {
           return pos + friction;
     }
}

当<代码>abs(pos)时,这会出现问题,如果你仔细研究你的物理,你会发现摩擦很可能是通过乘法来模拟的——这消除了你对符号的担忧。

当你想忽略符号时,使用
Math.abs
。请注意,优化可能会导致你的代码变得不可读且难以维护。因此,对于初学者来说尽量使你的代码尽可能干净,当你遇到性能问题时,通过基准测试确定问题的根源,只优化代码的瓶颈。

在物理学中,你的方向符号并不重要。我建议使用这样一个事实,即动摩擦力是一种与绝对值成比例的力运动中物体的速度。也就是说,物体在
[0,1]
范围内有一些摩擦系数
μF
。速度的变化就是
δV=μF∙v∙δt
其中
V
是物体的初始速度向量,
δt
是一段时间跨度

新的速度
V'
由以下公式给出

V' = V - δV
   = V - μFV∙δt
   = V(1 - μF∙δt)
V'=V-δV
=V-μF∙v∙δt
=V(1-μF∙δt)
这样,您根本不需要处理符号,它很容易扩展到更高维度的情况


另一方面,请确保δt足够小,不会在模型中引入振荡。

对,但dx>-friction或dx。顺便说一句,我曾经使用过这种编码,但发现它通常速度较慢。它似乎表现得最好,所以这就是我将使用的,谢谢。@SamuelWillems JIT在处理常见模式方面变得越来越聪明我的意思是,奇怪的把戏不像以前那样管用了,这几乎令人失望;)@SamuelWillems我知道你的意思。它曾经对奇数运算非常有用,比如在数组中添加所有奇数,但我发现在Java 8中使用条件更快Por use
int mult=Integer.signum(dx)
@slim精彩评论!我在错误的地方(在
java.lang.Math
中)寻找
signum
,但它不在那里。大约在1.5中引入此函数的同时,我停止了使用Java。非常感谢你!!!
dx = applyFriction(dx,friction);

int applyFriction(int pos, int friction) {
     if(pos > 0) {
           return pos - friction;
     } else {
           return pos + friction;
     }
}
V' = V - δV
   = V - μFV∙δt
   = V(1 - μF∙δt)