Compiler Nit Picky with Modulus

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Device=SAM4E16E

 

I am implementing a simple IIR 2 pole low pass butterworth filter with a circular buffer of length 4 using the modulus for my wrap around when N=0 and N>4. N is an unsigned char.  Example, when N=0:

 

k = N%4;                 // 0

km1 = (N-1)%4;       // Wrap around to get 3

km2 = (N-2)%4;       //wrap around to get 2

 

k, km1, km2 are used to index the y[k]'s and x[k]s.  When I am debugging my code i notice that if i use the above code, the modulus is not working with the km1 and km2. They are evaluating to 255 and 254 respectively, which kills the filter. 

But when I break the above into multiple lines:

 

k = N%4;                             // = 0

km1 = (N-1);                       //km1 = 255

km1 %= 4;                          //km1 = 3

km2 = (N-2)                        //km2 = 254

km2 %= 4;                          //km2 = 2

 

The code works, and the filter works as advertised. So my question, why is the compiler not evaluating km1 = (N-1)%4;  ? Why do I have to break this up into multiple lines? 

 

This topic has a solution.

Last Edited: Sun. Mar 12, 2017 - 04:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If N is 0, then (N-1) is a negative. Is that what you really want?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ezharkov wrote:
If N is 0, then (N-1) is a negative. Is that what you really want?

N is unsigned , so it's not negative, it's 2^n-1 , which is the point

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"unsigned char" is promoted to "signed int". Therefore, (N-1) is negative. Google "integer promotion".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ezharkov wrote:
"unsigned char" is promoted to "signed int". Therefore, (N-1) is negative. Google "integer promotion".

 

Changed the unsigned char to an unsigned int and it resolved the issue. Interesting to note that the (N-1) routine does not trigger the 'promotion'. (N-1) gives the wrap around to 255. It is the % combined with the (N-1) that was triggering it. 

Learn something new everyday. Thanks. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interesting to note that the (N-1) routine does not trigger the 'promotion'. (N-1) gives the wrap around to 255.

Sure it does.   but assigning to the unsigned variable "fixes" things.   It's the fact that "modulus" has somewhat odd behavior on negative numbers that is biting you. (we  expect %4 and &3 to give the same results, right?  Not with negative number!)