3
votes

Recently, I wanted to calculate the next multiple of 5 of several values. I was very confused by the output of this code, which should have done the trick:

7:11 - mod(7:11, 5) + 5
ans =
    7     8     9    10    11    12    13    14

While the actual working solution was this:

(7:11) - mod(7:11, 5) + 5
ans =

    10    10    10    15    15

So this seems to be related to operator precedence! But what exactly does the first command do, and why does it output a (1,8) vector?


Addendum: I have found that the first command can also be written as:

7:(11 - mod(7:11, 5) + 5)

Which already hints towards the explanation of the observed result, but I am still curious about the whole explanation.

1

1 Answers

5
votes

Here's the list of MATLAB operator precedence

As you can see, parentheses, (), are solved first, meaning that mod(7:11,5) will be done first. Then point 6), the addition and subtraction are taken care of from left to right, i.e. 11-mod(7:11,5) and then 11-mod(7:11,5)+5. Then point 7), the colon, :, gets evaluated, thus 7:11-mod(7:11,5)+5.

As you noted correctly 7:11 - mod(7:11, 5) + 5 is the same as 7:(11 - mod(7:11, 5) + 5), as seen above using operator precedence.


Now to the second part: why do you obtain 8 values, rather than 5? The problem here is "making an array with an array". Basically:

1:3
ans =
     1     2     3
1:(3:5)
ans =
     1     2     3

This shows what's going on. If you initialise an array with the colon, but have the end point as an array, MATLAB uses only the first value. As odd as it may sound, it's documented behaviour.

mod(7:11,5) generates an array, [2 3 4 0 1]. This array is then subtracted from 11 and 5 is added [14 13 12 16 15]. Now, as we see in the documentation, only the first element is then considered. 7:[14 13 12 16 15] gets parsed as 7:14 and will result in 8 values, as you've shown.

Doing (7:11) - mod(7:11, 5) + 5 first creates two arrays: 7:11 and mod(7:11,5). It then subtracts the two arrays elementwise and adds 5 to each of the elements. Interesting to note here would be that 7:12 - mod(7:11, 5) + 5 would work, whereas (7:12) - mod(7:11, 5) + 5 would result in an error due to incompatible array sizes.