This is a cautionary tale for developers who switch between programming languages often.
Whilst reviewing some logs, I noticed that durations of pauses between API requests were incorrect. They were expected to double on every subsequent attempt, starting from a fixed base interval; for example, 5 seconds, 10 seconds, 20 seconds, 40 seconds, and so on. Instead, they were changing in an odd manner: 15 seconds, 30 seconds, 60 seconds, 0 seconds, and so on.
A colleague and I reviewed the following C# code but did not spot anything wrong.
int tmp = RetryIntervalInMs * (2 ^ retryCounter);
These calculated durations kept puzzling me throughout the day as they were mathematically impossible given the programmed exponential growth.
Later that night, when I did some embedded development in C, I suddenly realised what was wrong.
I had used the
^ operator in C#, intending it to mean ‘raised to the power of’ as in some other language — which I cannot even remember now — whereas it was actually an XOR operator. Even two of us reviewing the code together did not spot that mistake.
The fix was to use the
Math.Pow(int, int) method, as follows.
int tmp = RetryIntervalInMs * (int)Math.Pow(2, retryCounter);