【问题标题】:addition with fixed min/max value具有固定最小值/最大值的加法
【发布时间】:2012-08-31 05:08:48
【问题描述】:

主要编辑:100% 解决!它被称为模数运算,谢谢彼得!

我需要添加两个具有固定最小值/最大值的数字。 我希望我的数字表现得像 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)

我投降

【问题讨论】:

  • 你的问题不是很清楚。你能改进措辞吗?
  • 在您的模数版本中,“值”应该是与 minValue 的偏移量,而不是实际值。相应地更正你的逻辑。
  • 您的问题是什么?或者您面临的问题是什么?
  • 我编辑了,但我不知道如何使它更清晰
  • 看来只有我明白你想要什么,matias

标签: java integer overflow modulo


【解决方案1】:

我会尽量把事情说清楚。例如

如果你想要时钟算法,你可以做

   // 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));

【讨论】:

  • 溢出后停止添加。如果你有 max_value=2,那将是 0+3=2,这是错误的。当它达到 value=2 时,它变为 0,但它不能停止加法。 0+3=1->2->0
  • 我想念你想要的时钟算法。更新了我的答案。
【解决方案2】:

试试

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);

【讨论】:

  • 溢出后停止添加。你的逻辑是说 Byte.MAX_VALUE + 3 等于 Byte.MIN_VALUE。这不是真的
  • 对不起,我误解了这个问题。现在我明白了。我已经相应地改变了。请检查。
  • 能否请您提及在您测试它的情况下的最大值和最小值是多少
  • 对于 value = -2,minValue = -2,maxValue = 1 添加 - 2 返回 -4。超出范围
  • 我只是在检查彼得的解决方案。当 minValue=maxValue 时它似乎不起作用。例如 minValue=maxValue=3。在这种情况下,值只能等于 3。尝试向其添加 5。它有效还是我在某个地方错了?
【解决方案3】:

好的!

你不会喜欢这样,但它可以让你避免加法操作:

(请注意代码是 C#,因为我这里没有 java)看起来像这样:

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];
    }
}

【讨论】:

    猜你喜欢
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    相关资源
    最近更新 更多