Is there a way to implement this very simple logic logic using only mathematical operands (such as mod)?

I want to reduce the value by one, and if it reaches zero, set it to the maximum value. Is there a way to do this using math without resorting to if (n-1 == 0) { n = max; } if (n-1 == 0) { n = max; }

The opposite scenario of increasing the value by one, and then setting it to zero when it is greater than max, can be easily achieved with n = (n + 1) % (max + 1); . In addition, it is even better, since you can increase any amount (not just one), and it will still β€œturn around” correctly.

Thanks for the answers so far. To be clear, I meant without logical logic (if / else) or logical operators (!, & &, Etc.) in general. I was just curious how to do this. Does the correct answer actually make it more unreadable if a comment is provided? It would be necessary to use this for a more general case to subtract an arbitrary number and expect the correct wrapper.

+6
language-agnostic math algorithm
source share
11 answers
 n = max - ((max - n +1)%max) 
+6
source share

If you do this solely for performance reasons, I would advise doing so. % usually a fairly expensive operation on most architectures - simple comparisons, branching and adding will usually be more efficient. Of course, the usual speculative / premature optimization warnings apply.

+5
source share

The problem is that the % operator in C returns a negative result when faced with a negative dividend. This is often not what you need.

If you need a mod function that will execute -1 mod n == n-1 , then in C you need to do the following:

 int mod(int a, int b) { return (a%b + b) % b; } 

Then you can do

 n=mod(n-1, max+1); 

to decrement n and wrap it to max when n==0 . Note: as for the increment case, this will work for an arbitrary step size.

+1
source share

In mathematics there are enough variations between languages, and I doubt that this is a language-agnostic way of doing this. There are simply too many changes in how languages ​​write expressions for a basic unified method for working with any possible language.

If you choose a specific language, there will be a very good chance that this is possible. For example, in C or C ++ you can do something like: n = (n-1) + ((n-1) == 0) * max;

If you're curious how this works: in C, a comparison ( == in this case) produces a result of 0 for false and 1 for true. So what we do is add max * 0 when / if n-1 != 0 and max * 1 when / if n-1 == 0 .

+1
source share

There may be a better way, but I think n = max - (max - n + 1) % (max + 1) works. I assume that you want to include 0 at both ends, since for your increment expression you include 0.

0
source share

In fact, you can also do

 n = (n - 1) + ((!(n - 1)) * max); 
0
source share

What about:
n =! n * max + (!! n) * n;

0
source share

Re: no booleans
Well, through the magic of integer division (C-style), my previous answer can be written like this:
n = ((max-n) / max) * max + ((max + n-1) / max) * n;

0
source share

Just ask: why do you want to avoid logical operation?

If you want to avoid conditional code in your application, you can use logical expressions that are stored in boolean values. They will be mapped to SETcc instructions on the i386, and I assume that analog settings exist in other ISAs.

In this case, you can use a boolean expression and still have non-conditional code, and you can use:

Assuming that the logical result of truth is Ordinal 1 (this is the case in Delphi code), and the logical value false is 0, you can write

 next := current - 1 + ( ( 1 + max ) and -Ord( current = 0 ) ); 

Do not vote for this because I gave an answer with logical operations. I just want to check if this is a differnet solution for the main problem.

However: I think conditional code is much more readable.

0
source share

Why not just compare with 1?

if(n==1) { n = max; }

-one
source share

In any short circuit logic evaluation language (most modern languages) you can do something like this:

--n<=0 && n=max;

You can get a hairy eyeball from your colleagues if your team is not used to using && as an if-then operator.

To increment a direct loop:

++n>max && n=1;

These examples take a 1-index counter, since your question seems to suggest this. 0-indexed equivalents:

--n<0 && n=max-1;

++n>=max && n=0;

-one
source share

All Articles