Overflowing array help please?

Hi Paul,

I have been researching % and still have not understood it as it yields different results to what i expect. My comments from a week or two back show how I hacked it to work but still no elegant solution. I am here to learn but telling someone to research clearly doesn't help when they are already doing their best.

Whenever you change the array index or use a version of it with something added or subtracted, you use "%" to get the remainder from NUM_LEDS to use as the actual index. The remainder will always be between (including) zero and one less than NUM_LEDS, so will be pointing within the array - and will loop around as you want it to. :sunglasses:

The remainder will always be between (including) zero and one less than NUM_LEDS, so will be pointing within the array

that's not always true

You have this:
#define NUM_LEDS 200
--> Mind negative values when doing modulo operations and be careful with the implicit type of a #define (a signed int)

You need to make sure the total count used for the modulo is a uint16_t . Test this for example:

int value = -5;
#define totalCountSigned 200 // will be seen as a signed integer
const uint16_t totalCountUnsigned = 200; // an operation involving an unsigned larger than a byte will get promoted to unsigned calculation if the size is large enough (16 bits will do)

void setup() {
  Serial.begin(115200);
  Serial.print("Signed modulo : "); Serial.println(value %  totalCountSigned);
  Serial.print("Unsigned modulo : "); Serial.println(value %  totalCountUnsigned);
}

void loop() {}

Serial Monitor (@ 115200 bauds) will show

Signed modulo : -5
Unsigned modulo : 131

so as you can see, using a #define for the count is not a good idea as you get a signed computation and modulo does not know how to deal with this.

if you use an uint16_t, the -5 gets promoted to its unsigned representation so (65536-5) and then the modulo is applied, that's why you get 131.

This might not be what you expected though. So my advice would be to handle the circular buffer "manually" by testing with an if clause the calculated index and finding the right matching position if that index is negative / beyond bounds.

thanks Paul,

I understand the basic concept of % but for what ever reason i cannot get it to behave in my code..

for example these two if statements below should overflow the array at each ends but the first one would not work if I used

leds[(randomLED-i)% NUM_LEDS] = ColorFromPalette(currentPalette,randomColor,paintballBrightness,LINEARBLEND);

so i had to modify it to do calculate calc first which works but makes no sense to me...

 if (randomLED-i < 0){                                                                                      // i have no idea how to use modulo % in an array 
          calc = (randomLED-i)% NUM_LEDS;                                                                          // leds[(randomLED-i)% NUM_LEDS] doesnt work 
          calc = NUM_LEDS - abs(calc);                                                                             // so ive made this ugly shit.... :(
          leds[calc] = ColorFromPalette(currentPalette,randomColor,paintballBrightness,LINEARBLEND);
        } 
        
        if(randomLED+i >= NUM_LEDS-1){
          leds[(randomLED+i)%NUM_LEDS] = ColorFromPalette(currentPalette,randomColor,paintballBrightness,LINEARBLEND);  
          leds[randomLED-i] = ColorFromPalette(currentPalette,randomColor,paintballBrightness,LINEARBLEND);

see my answer #23 above

Thanks heaps! I'm checking it out now.