The latest issue of Computing reported an amusing error in their “BackBytes” column.
Go to:
http://www.nationalrail.co.uk/
and say that you want to travel from Oxford to Hawarden at 8am tomorrow. (I’m not sure how relevant the time is, and I think any day will do.) When it comes up with the results, click on the “Check fares” button. This produces the following results:
The cheapest available fare is: £179,769,313,486,231,570,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000.00
Presumably this is a basic ticket, because there are no first class tickets available for that journey. Personally, I’d expect to at least be guaranteed a seat if I was spending a bazillion pounds on a ticket!
More precisely, there are 97 blocks of “000” before the decimal point, so that price is roughly equal to £1.79 x 10308. This is a special number, so you should be suspicious if you encounter it! Most people who work in IT will recognise common powers of 2; for instance, if you know that a number has to be between 0 and 255 then it’s probably being stored in an 8-bit field. In this case, the price is also roughly equivalent to 21024 = 2210, which is the largest value that can be stored in a double (64 bit) variable; I’ve come across this in database documentation, e.g. for SQL Server’s float.
I reported the problem to National Rail via their website, on the basis that it’s a bit mean just to laugh at them, so you may get different results if you repeat this search later. They replied:
“You will notice that despite the fact that you are told this is the fare there are no tickets available on any services at any price and this is what causes the error.”
Based on that, I can guess the algorithm they’re using:
- Declare “cheapest fare” as a double.
- Initialise cheapest fare to be the maximum value that can be stored in a double.
- Loop through the list of available tickets. For each one:
- If this ticket is cheaper than the current cheapest fare, make the cheapest fare equal to this ticket.
- Return cheapest fare.
This assumes that you have at least one ticket available, but it breaks if you don’t. The solution would be to also use a Boolean variable as a flag, e.g. “found cheapest ticket”. Initialise it to false in step 2, then set it to true in step 3. In step 4, inspect the flag before returning the cheapest fare.
This type of mistake doesn’t just apply to train fares, so it’s worth watching out for in any other programming.