How to get a positive sign for a result from a mod in bash

When naively using the mod command in bash, the residual character of the error value (in my opinion) for negative numerators:

If I write:

for i in {-5..5}; do echo $(( $i % 3 )) ; done 

I get output (as a string)

 -2 -1 0 -2 -1 0 1 2 0 1 2 

How to achieve the β€œright” behavior

 1 2 0 1 2 0 1 2 0 1 2 
+5
source share
2 answers

Add 3 , and then Mod 3 to the first result set:

 $ for i in {-5..5}; do printf "%d " $(( (($i % 3) + 3) % 3 )) ; done 1 2 0 1 2 0 1 2 0 1 2 

If you know the maximum range, you can simply add a significantly larger number of multiples of 3 to make all numbers positive until the first modulo operation.

 $ for i in {-5..5}; do printf "%d " $(( ($i + 3000000) % 3 )) ; done 

However, the first approach is cleaner and more universal.

Finally, for fun:

 positive_mod() { local dividend=$1 local divisor=$2 printf "%d" $(( (($dividend % $divisor) + $divisor) % $divisor )) } for i in {-5..5}; do printf "%d " $(positive_mod $i 3) done 
+3
source

According to wikipedia , negative signs are allowed.

[Result of a mod n ] this still leaves the sign ambiguous if the remainder is non-zero: there are two possible options for the remainder, one negative and the other positive, and two possible options for the quotient. Usually in number theory, a positive remainder is always chosen, but programming languages ​​are chosen depending on the language and the signs a or n.

So it depends on the programming language to define it. Since bash obviously went for a "negative remainder", you could escape, for example. perl like this:

 for i in {-5..5}; do perl -le "print $i%3"; done 

This is due to the launch of the Perl interpreter separately for each whole.

Really! Since the OP seems to care about the right math, you might consider switching to something like python and doing a loop and all that is there.

+2
source

Source: https://habr.com/ru/post/1263102/


All Articles