我需要写一个在最小值和最大值之间 "循环 "的整数。如果达到最大值,你加1,它就会跳到最小值。如果从最小值中减去1,则达到maxValue。
例如:minValue=2;maxValue=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只是为了在计算中消除它,以后再加。
有没有已知的算法?如果没有,你知道减法算法是怎样的吗?
首先将模数应用于 b
并减去最小值 a.value
int range = a.maxValue + 1 - a.minValue;
b %= range;
int value = a.value - a.minValue;
允许负值。b
现在将大于 -range
且低于 range
.
此外,增加 b
和 range
至 value
,并应用模数。添加 range
必须在 b
是一个负数。负数的加法和正数的减法是一样的。
int result = (value+range+b) % range;
对于减法来说,将负数和正数相加。range
至 value
前减 b
,并应用模数。这样做的原因是 (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
取代
int sum = a.value + b;
与
int sum = (a.value - b + ( (b / range) * range) );
哪儿
int range = a.maxValue + 1 - a.minValue;
应该没问题