在Java中降低一个变量直到达到某个数字。

3

我有这个类:

public class Vehicle {
    private float speed;

     public void decelerationSpeed()
     {
         --speed;
     }  
}

每次调用“decelerationSpeed”方法时,速度变量会减少一。
我需要以这种方式更改“decelerationSpeed”方法,即如果速度变量达到零并且调用了“decelerationSpeed”方法,则不必更改速度值。
在本教程中,我不能使用if else或任何其他条件运算符(我认为我必须使用模数和除法运算)。

我现在无法测试,因此不会将其添加为答案,但也许这个方法会起作用:speed +=(speed%1)-1 - aleb2000
这个重复代码有几种方法可以用于“max”,但是很容易调整为适用于“min”也。 - Tom
每次减少后都要检查最小值:--speed; if( speed < 0f ) speed = 0f; - markspace
@Tom 他说他不能使用 if-else 语句。 - aleb2000
显示剩余6条评论
5个回答

1
我们总是希望减一,除非我们的速度为零,因此模运算是适当的,因为0 mod y0,而对于任何其他数字,我们希望x mod y的结果为1。符合这些条件的模运算是x % (x - 1)。然后两个特殊情况是1和2,其中1会给出0的余数,而2 mod 1没有效果。因此,我们通过预备加法和随后的减法将它们排除在可能的值集之外:
   public void decelerationSpeed()
     {
        speed = speed + 2;
        speed = speed - ((speed) % (speed-1));
        speed = speed - 2;
     }

0
一个使用Java浮点数转整数的好方法如下所示:
speed -= (int) ((speed / (speed + 1.0) + 0.6));

基本思路是Java通过舍弃小数位将浮点数转换为整数。因此,我们只需要以一种方式生成一个值v,使得如果输入为0,则0 <= v < 1,否则1 <= v < 2。如果speed为0,则speed / (speed + 1.0)为0,否则至少为0.5且最多(在数学上至少)接近1。将所有这些移动0.6(以确保我们肯定会超过1),就可以得到所需的序列。其余部分只需去掉小数位即可。
一个非常丑陋(但更简单)的方法如下:
void decrement()
{
    try{
        int throwaway = 1 / speed;
        speed--;
    }catch(ArithmeticException e){
        //just ignore the exception
    }
}

如果速度可以在0和1之间取值,那么这种方法不起作用。 - Bubletan
@Bubletan 抱歉,完全忽略了那个约束条件。 - user4668606
@Paul 我认为这不是一个限制。速度值相对于整个 int 步骤是离散的。因此,尽管速度是浮点数,但您永远不会在 0 和 1 之间的某个值开始或结束。这是假设加速也以 int 步骤发生的情况。 - Anatoly
@Anatoly 嗯,我想这是一个有点奇怪的问题。如果 OP 能够澄清一下会更有帮助... - user4668606

0

我不知道是否允许位转换,但这是一个解决方案:

speed -= 1;

int bits = Float.floatToRawIntBits(speed);
bits &= (bits >>> 31) - 1;
speed = Float.intBitsToFloat(bits);

首先,我们获取符号位(bits >>> 31),并从中减去1以获得掩码:0xffffffff表示正数,0x00000000表示负数。使用此方法将会把每个负数变成+0

这不是一个优美的解决方案,但它有效。


Float.floatToIntBits 在其实现中使用了 IfFloat.floatToRawIntBitsFloat.intBitsToFloat 也是这样做的吗? - Omid
@omid 我不认为他们会,但我可能错了:http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/native/java/lang/Float.c - Bubletan

0
如果您可以使用Math.sqrt函数,那么可以使用以下方程式。
(val+|val|)/2

基本上,任何负数都会减去自身变成0。

这是一些代码展示:

public static float decelerationSpeed(float speed) {
    speed -= 1; // subtract
    // use (val+|val|)/2 to zero out any negative numbers. Divide by 2 to return to origional number
    return (float) (speed+Math.sqrt(speed*speed))/2f;
}

public static void main(String [] args) throws Exception {
    System.out.println(assertF(decelerationSpeed(-10), 0));
    System.out.println(assertF(decelerationSpeed(10), 9));

    System.out.println(assertF(decelerationSpeed(-2), 0));
    System.out.println(assertF(decelerationSpeed(2), 1));

    System.out.println(assertF(decelerationSpeed(-1), 0));
    System.out.println(assertF(decelerationSpeed(1), 0));

    System.out.println(assertF(decelerationSpeed(-0), 0));
    System.out.println(assertF(decelerationSpeed(0), 0));
}

public static float assertF(float actual, float expected) {
    if(actual != expected) throw new IllegalStateException("Expected "+expected+" but got "+actual);
    return actual;
}

-2
这是我如何回答这个问题。传入int,short,float或double等类型都可以:
public class HelloWorld
{
  private static float speed = 1113; // initial speed
  private static short smallIncrement = 13;

  public static void main(String[] args)
  {
      decelerateAndReturnSpeed(2.33); // prints 1110.67
      decelerateAndReturnSpeed(7.33f); // prints 1103.3401
      decelerateAndReturnSpeed(113); // prints 990.3401
      decelerateAndReturnSpeed(smallIncrement); // prints 977.3401
  }

  public static float decelerateAndReturnSpeed(double vAmt)
  {
    speed -= vAmt;
    if (speed < 0) speed = 0;
    System.out.println(speed);
    return speed;
  }
}

现在,这是因为编译器会像这样进行计算,使用隐式转换:
speed = (float)(speed -vAmt);  // same as speed =- vAmt

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