Search code examples
bashmodulo

How to get positive sign for result from mod in bash


When naively using the mod command in bash the residual gets the wrong sign (in my opinion) for negative numerators:

If i write:

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

i get the output (as a row)

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

How do i achieve the "correct" behavior

1 2 0 1 2 0 1 2 0 1 2

Solution

  • Rather than loop until the result is positive or launch perl or python consider the following:

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

    this will result in the OP's desired output.

    This works because the first modulo will bring the result into the range -3 to 3, adding 3, causes the result to be in the range 0 to 6, we can then perform modulo again (adding 3 has no effect on this).

    in general: mod = ((a % b) + b) % b