Go gotcha: What's wrong with the remainder (modulo) operator?

Why isn't -1 odd?

func Odd(n int) bool {
        return n%2 == 1
}

func main() {
        fmt.Println(Odd(-1)) // false
}
Answer

The remainder operator can give negative answers if the dividend is negative: if n is an odd negative number, n % 2 equals -1.

The quotient q = x / y and remainder r = x % y satisfy the relationships

x = q*y + r  and  |r| < |y|

where x / y is truncated towards zero.

 x     y     x / y     x % y
 5     3       1         2
-5     3      -1        -2
 5    -3      -1         2
-5    -3       1        -2

(There is one exception: if x is the most negative value of its type, the quotient q = x / -1 is equal to x. See Compute absolute values for more on this anomaly.)

One solution is to write the function like this:

// Odd tells whether n is an odd number.
func Odd(n int) bool {
        return n%2 != 0
}

You can also use the bitwise AND operator &:

// Odd tells whether n is an odd number.
func Odd(n int) bool {
        return n&1 != 0
}

Comments

Be the first to comment!