The %
operator is called the "Modulo" operator.
It is used to return the remainder of a division. For example:
5 % 2
returns 1
because 5/2
gives us 2
and a remainder of 1
.
5 % 4
returns 1
because 5/4
gives us 1
and a remainder of 1
.
8 % 8
returns 0
because 8/8
gives us 1
and there is no remainder.
10 % 3
returns 1
because 10/3
gives us 3
and a remainder of 1
.
10 % 2
returns 0
because 10/2
gives us 5
and there is no remainder.
1 % 4
returns 1
, because 1/4
gives us 0
and the remainder is 1
.
2 % 5
returns 2
, because 2/5
gives us 0
and the remainder is 2
.
How does that help anything, why do I need it?
We mostly use it in two cases:
- We want to know if a number is even or odd; we can use
% 2
, and see if we obtain 0
(even) or 1
(odd).
- We want to wrap a number over a range.
The second one is complicated to ... wrap... your head around, so here's a demonstration.
Suppose we have an array of 4 items, and we want to continuously pick a valid index by incrementing an index.
var letters := ["a", "b", "c", "d"]
var initial_index := 0
func get_next() -> void:
var next_initial_index := initial_index + 1
initial_index = next_initial_index % letters.size()
When I run get_next()
the first time, next_initial_index
becomes 1
.
We know letters.size()
is 4
.
If we run modulo on next_initial_index
, we obtain still just 1
.
1 % 4
returns 1
, because 1/4
gives us 0
and the remainder is 1
When we increment next_initial_index
we obtain 2
. 2 % 4
give us 2
.
And so on, until 4
. What does 4 % 4
return? Yes, the result of the division 4 / 4
is 1
, and the remainder is 0
.
What does 5 % 4
return? That's right, 1
! And 6 % 4
return? That's right, 2
!
And so on. No matter how much we increment next_initial_index
, we obtain a result between 0
and 3
. The index will always be valid.