Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I modulo when my numbers start from 1, not zero?

Tags:

modulo

I guess the solution for this is quite simple, but I've been thinking about it for a while and couldn't come up with an elegant solution.

I have a range of numbers, e.g. 1..10 = (1,2,3,4,5,6,7,8,9,10), which is circular, meaning the number after the last one is again the first one (next(10)=1).

For a given number i>0 in the range, I would like to calculate the next m-th, and previous m-th number. e.g. next(5,1)=6 next(10,1)=1 next(10,2)=2 prev(5,2)=3 prev(1,1)=10 prev(1,2)=9.

For next I can just take (i+m)%n where n is the length of the range (n=10 in the example). But for prev I couldn't find an elegant solution.

like image 343
David B Avatar asked Sep 27 '10 11:09

David B


People also ask

Is modulo always 1 or 0?

The range of values for an integer modulo operation of n is 0 to n − 1 inclusive (a mod 1 is always 0; a mod 0 is undefined, possibly resulting in a division by zero error in some programming languages). See Modular arithmetic for an older and related convention applied in number theory.

Can you do mod with negative numbers?

The modulus of a negative number is found by ignoring the minus sign. The modulus of a number is denoted by writing vertical lines around the number. Note also that the modulus of a negative number can be found by multiplying it by −1 since, for example, −(−8) = 8.

Can you modulus by 0?

If you're trying to talk about modular arithmetic with a modulus of 0, that would be nonsense. All numbers = to, say m < n mod(n), have the same remainder m when divided by n. Since mod(0) would thus require division by 0, which is undefined, mod(0) would also be undefined.

What is the modulo of 1?

1 mod 1 = 0 (as mod 1 is always 0)


1 Answers

Just subtract 1 and add 1 afterwards.

In most programming languages, you need to watch out when finding a "previous" value, because for negative numbers, modulo does not work as you want in this case: it returns a negative number.

Here's the C/C++ version:

int next(int i, int m, int n) { return (i + m - 1) % n + 1; } int prev(int i, int m, int n) { return (i - m + n - 1) % n + 1; } 

However, in Perl modulo always returns a positive value (at least when the second operand is a positive integer). Basically it does what you want. So you can write the following and leave out the + $_[2]:

sub nxt { ($_[0] + $_[1] - 1) % $_[2] + 1; } sub prv { ($_[0] - $_[1] - 1) % $_[2] + 1; } 
like image 149
gpvos Avatar answered Oct 11 '22 10:10

gpvos