Loop modulus within range simplification

alnun

New member
Joined
Jul 7, 2021
Messages
2
I was solving a cipher problem with JavaScript and wanted to merge encoding and decoding functions.
In order to do that I needed a function that returns a number in a range in a cyclic way.
Knowing the properties of the modulo function, that returns the remainder of a division, by trial and error I reached this result:

- k(n,i,a):=mod(mod(n-i,-i+a+1)-i+a+1,-i+a+1)+i

Where 'n' is the number i want to put in the cycle, 'i' is the minimum in the range and 'a' the maximum.

The function in JS:
JavaScript:
  circularNumberInRangeBothWays(num, min, max) {
    const diff = -min + max + 1
    return ((num - min) % diff + diff) % diff + min
  }

In the image I have the proof that it works at least for the range I need.
I would like to know if the function is correct, and if it is in its simpler form. It have to work only with integers.
Thank you for your time.
 

Attachments

  • range.png
    range.png
    41.1 KB · Views: 3
I suspect your question is due to the fact that remainder ( "%" in java) is not the same as modulo in maths when it comes to negative numbers.

with a remainder operation, (-1) % 3=-1
with a modulo operation, mod(-1, 3) = (-1) mod 3 = 2

Your desired expression, in its simplest form, is mod( n - i, a+1-i ) + i
The red "-i" provides an offset, do you need this? And will the input n ever be -ve? You might be able to circumvent this issue by ensuring that the first argument to % is always positive. However, if your function needs to cope with negative numbers, then the code that you've shown is a possible solution.

Basically if a can be -ve or +ve AND b>0 then here's two ways of implementing r=mod(a, b) in java:-
Java:
    r=(a%b + b)%b; // This is the method used in the function you've shown
OR
    r = a%b;
    if (r<0) r += b;
 
You nailed it. The input 'n' was receiving negative values.
I didn't knew about the difference between the remainder and the modulo operation.
Thank you very much!
 
Top