1

主な編集:100%解決しました!それはモジュラー算術と呼ばれていますピーターに感謝します!!

最小/最大値が固定された2つの数値を追加する必要があります。数値をjavaのint/byte / shortのように動作させたい(反対の値にオーバーフローして操作を続行する)

System.out.println((byte) (Byte.MAX_VALUE));    // 127
System.out.println((byte)(Byte.MAX_VALUE + 1)); // -128
System.out.println((byte)(Byte.MAX_VALUE + 2)); // -127
System.out.println((byte)(Byte.MAX_VALUE + 3)); // -126

ただし、.MAX_VALUEと.MIN_VALUEは固定されています。数値の値が3で、maxValueが5、minValueが2の場合、それに4を追加すると(3 + 4 = 7である必要があります)、オーバーフローするため、3 + 4:3-> 4-> 5-> 2- > 3例:

    int value = 0, minValue = -2, maxValue = 1;
    MyNumber n = new MyNumber(value, minValue, maxValue);

    // possible values: -2 -1  0  1 -2 -1  0  1 -2 -1  0  1 ..

    n.add(2);   // 0+2 = -2
    n.add(-2);  // -2-2 = 0
    n.add(5);   // 0+5 = 1       
    n.add(-5);  // 1-5 = 0       
    n.add(-5);  // 0-5 = -1       
    n.add(-1);  // -1-1 = -2       
    n.add(11);  // -2+11 = 1

これは私がしたことです:

class MyNumber {

    int value;
    final int minValue, maxValue;

    public MyNumber(int value, int minValue, int maxValue) {
        if (value < minValue || value > maxValue || maxValue < minValue) {
            throw new RuntimeException();
        }
        this.value = value;
        this.minValue = minValue;
        this.maxValue = maxValue;
    }

    void add(int amount) {
        int step = 1;
        if (amount < 0) {
            step = -1;
            amount = -amount;
        }
        while (amount-- > 0) {
            value += step;
            if (value < minValue)
                value = maxValue; // overflows
            if (value > maxValue)
                value = minValue; // overflows
        }
    }
}

それは機能しますが、大きな数値で作業するので、追加全体を繰り返したくありません。MODと関係があると思います...(数学ではひどいです)ほぼランダムにこれを作成しました:

void add(int amount) {
    value = (value + amount) % (maxValue - minValue + 1);
}

私はとても近かったが、それは失敗する

n = new MyNumber(-2, -4, -1);
n.add(2); // -2+2 shows 0 instead of -4   (-2.. -1.. *overflow*.. -4)

私は降伏します

4

3 に答える 3

2

私は物事をできるだけ明確にしようとします。例えば

クロック演算が必要な場合は、

   // in the constructor
   this.range = maxValue - minValue + 1;
   this.value = -minValue;

   // in the adder.
   public void add(int num) {
       value = (value + num) % range;
       if(value < 0) value += range;
       // or
       value = ((value + num) % range + range) % range;
   }


   // add a getter for value.
   public int getValue() { return value + minValue; };

有界算術が必要な場合。

    value = Math.min(maxValue, Math.max(minValue, value + step));
于 2012-08-31T05:51:58.270 に答える
1

試す

value += amount;

value = value > maxValue ? maxValue : value < minValue ? minValue : value;

これはうまくいくはずです。

変化 :

range = maxValue == minValue ? 0 : Math.abs(maxValue - minValue + 1);
value = range == 0 ? maxValue : value + amount <= maxValue && value + amount >= minValue ? value + amount : value + amount > maxValue ? minValue + (((value + amount - maxValue) % range) == 0 ? range : (value + amount - maxValue) % range) - 1 : maxValue - ((Math.abs(amount) - Math.abs(value - minValue + 1)) % range);
于 2012-08-31T05:22:21.937 に答える
0

Ok !

これは気に入らないでしょうが、追加操作を回避することができます。

(ここにはJavaがないため、コードはC#であることに注意してください)次のようになります。

class MyNumber 
{    
    public int value;
    int minValue, maxValue;
    private int[] range; 
    private int index = 0;

    //Ctor
    public MyNumber(int value, int minValue, int maxValue) 
    {
        if (value < minValue || value > maxValue || maxValue < minValue)            
            throw new Exception("...");

        this.value = value;
        this.minValue = minValue;
        this.maxValue = maxValue;
        range = new int[maxValue - minValue + 1];
        for (int i = 0; i < range.Length; i++)
        {
            range[i] = minValue;
            if (range[i] == value)
                index = i;
            minValue++;
        }
    }

    public void add(int amount)
    {
        if (Math.Abs(amount) > range.Length)
            amount %= range.Length;

        index = Math.Abs(index + amount);
        if (index >= range.Length)
            index %= range.Length;

        value = range[index];
    }
}
于 2012-08-31T06:59:47.267 に答える