How to properly overflow 2D coordinates on an overflowing/circular map?

I made a simple Snake game designed for trying Snake bots. I thought the base map functions work, but now I found there is an error. What I need is to properly translate any coordinates outside the actual map to coordinates within it.

For example, if you’re at the right edge of a 10×10 map and you go to (zero-indexed) [10, 5], you’d expect to pop out at [0, 5]. That works in my implementation, but not the negative overflow. I tried a lot of formulas in the dev console and just can’t figure it out. Consider this code:

    /**      * Normalizes overflow of a point so that it is within the map      * @param {number|Vector2} x      * @param {number} y      * @returns {Vector2}      */     normalizePoint(x, y) {         if (x instanceof Vector2) {             y = x.y;             x = x.x;         }          // auto overflow         if (x >= this.size) {             x = (x % this.size);         }         else if (x < 0) {             // ???         }         if (y >= this.size) {             y = (y % this.size);         }         else if (y < 0) {             // one of the formulae I tried, does not work for all values             y = this.size + (y-1) % this.size;         }         return new Vector2(x, y);     } 

Vector2 is a simple object with properties x and y. this.size represents the map size. For negative coordinates, I am not getting the correct results. I want overflowing X and Y coords to resolve to the same numbers. For example for a 5×5 map, all rows should be equal X coords after normalizing:

Real map coord X: 0 1 2 3 4
Negative alternatives: -5 -4 -3 -2 -1
Negative alternatives: -10 -9 -8 -7 -6

I would prefer it to be a O(1) formula, rather than some weird loop. With a loop, I solved it like this:

if (x < 0) {             while (x < 0) {                 x += this.size;             }         }  ```