循环整数

Circulating integer

我需要写一个 "circulates" 介于最小值和最大值之间的整数。如果达到最大值并加 1,它会跳到最小值。如果从最小值中减去 1,就会达到最大值。


示例:
最小值 = 2;
最大值 = 10;

导致:... 2,3,4,...9,10,2,3,...


我想通了加法算法,但我被减法卡住了。 添加看起来像这样:

public static circularInt operator +(circularInt a, int b)
{
    int sum = a.value + b;        
    int circularValue = ((sum - a.minValue) % (a.maxValue + 1 - a.minValue)) + a.minValue;

    return new circularInt(circularValue, a.minValue, a.maxValue);
}

基本上算法可以分解为"newValue % range"。所有的+- minValue只是为了从计算中剔除它,稍后再添加它。

是否有已知的算法?如果没有,您是否知道减法算法可能是什么样子?

正在替换

int sum = a.value + b;

int sum = (a.value - b + ( (b / range) * range) );

哪里

int range = a.maxValue + 1 - a.minValue;

应该没问题!

首先将模数应用于 b,然后从 a.value

中减去最小值
int range = a.maxValue + 1 - a.minValue;
b %= range;
int value = a.value - a.minValue;

允许负值,b 现在将大于 -range 且小于 range

对于加法,将 brange 添加到 value,然后应用模数。当b 为负数时,需要加上range。加一个负数和减一个正数是一样的。

int result = (value+range+b) % range;

对于减法,在减去 b 之前将 range 添加到 value,然后应用模数。这是可行的,因为 (value+range) % range == value 所以添加范围不会改变最终结果,但它确实可以防止中间结果变为负值。

int result = (value+range-b) % range;

通过将最小值加回

完成
int circularValue = result + a.minValue;

这是最终代码,由 @Meister der Magie

提供

加法:

public static circularInt operator +(circularInt a, int b)
{
    int range = (a.maxValue + 1 - a.minValue);
    b %= range;
    int value = a.value - a.minValue;

    int additionResult = (value+range+b) % range;

    int circularValue = additionResult + a.minValue;
    return new circularInt(circularValue, a.minValue, a.maxValue);
}

减法:

public static circularInt operator -(circularInt a, int b)
{
    int range = (a.maxValue + 1 - a.minValue);
    b %= range;
    int value = a.value - a.minValue;

    int subtractionResult = (value+range-b) % range;

    int circularValue = subtractionResult + a.minValue;
    return new circularInt(circularValue, a.minValue, a.maxValue);
}

这应该让您对公式有所了解:

private const int MinValue = 2;
private const int MaxValue = 10;

public static int AddCircular(int a, int b)
{
    int modulo = MaxValue - MinValue + 1;
    int sum = (a - MinValue + b) % modulo + MinValue;
    if (sum < MinValue) sum += modulo;
    return sum;
}

输出:

AddCircular(2,-1);
10
AddCircular(10,1);
2