I hope this blog post illustrates the importance of testing your code thoroughly, first let’s have a look at the issues I discovered in video form.

Now to explain What’s going on. As I outlined in my previous post, the UK is split into 100km squares, each labelled with a 2 letter code. So I went to the border of two squares (\(TA\) and \(TF\), marked with the red cross on the map), to see how well it worked. I managed to find quite an interesting bug in my code due to when I round and when I use the \( \bmod \) operation. So what happens, is when I get 50m south of the dividing line, the grid reference gets displayed as \(TF;044;1000\) instead of \(TA;044;000\), which has an extra column, which (as I’m not clearing the screen every update on the screen) then displays an additional \(0\) at the end of \(TF;044;999\)

Preview of an OS map

Now to look at the offending code

  unsigned int new_northing = (int)(500000.5 + NE.Northing); // rounds to nearest 1m

// Calculates grid square
    unsigned char nl1 = new_northing / 500000;
    unsigned int n = new_northing % 500000;
    unsigned char nl2 = n / 100000;
// gets value within given square
    unsigned int n2 = n % 100000;

// el1, el2 and e2 calculated by a similar method

    string_t ref;

    string_t s;
    s += alphabet[(int)el1 + 5 * (4 - nl1)];
    s += alphabet[(int)el2 + 5 * (4 - nl2)];
    s += " ";
    s += format((e2 + 50) / 100, 3); 
    s += " ";
    s += format((n2 + 50) / 100, 3); // rounds nearest to 100m here
    return s;

Aside Rounding to the nearest 100m: Because integer division in C++ truncates (removes any decimal places, rounding down), to round \(x\) to the nearest value (say \(2n\) ) when dividing, you need to calculate \(\frac{x+n}{2n}\) instead of \(\frac{x}{2n}\)

It may not be immediately obvious what the issue is here, but what happened is I rounded to the nearest 100m too late, meaning that If i was at a value \(t, 99950 \leq t < 100000\) when rounded to the nearest 100m would round up to 100000 for the value, but not in the grid square. This only affects 50m every 100km in each direction (or 0.099% of one of these squares), but luckily, an easy fix can be found by rounding to the nearest 100m at the start, like so

  unsigned int new_northing = (int)(500050 + NE.Northing); // rounds to nearest 100m

  // Other Code Unchanged

    s += format(n2 / 100, 3); // no rounding here
    return s;