In college I followed a course in numerical analysis. The main point of the course was to be careful with floating point arithmetic, because it is vulnerable to rounding errors that can significantly influence the result of complex computations. Until yesterday I never had encountered such a problem. Now that I have lost my innocence in this matter, I would like to share my tale of nasty debugging and frustration.
After receiving some bug reports of Floorplanner designs that failed to save properly, we dove into the code to see what was going wrong. After some time, we found that the errors were caused by the script that loads the design after it has been saved with a unique name. This unique name is passed to the script to be able to find the design. We used the current timestamp as a unique name for the design. The current timestamp simply is the number of seconds passed since January 1, 1970 and looks something like this: 1206712028. As a design name, this number was passed to different scripts, both client-side and server-side. However, at some point in this chain of scripts, the number was changed slightly to 1206712030 and because of this the associated design could not be found, resulting in an error.
At first, we investigated the possibility that the stored timestamp was overwritten by a newer timestamp, as this could explain the slight increase in the number. However, we were not able to find this anywhere in the code and sometimes, the number was decreased a bit instead of being increased.
Finally, we monitored the data being sent between the different scripts, and we found that ActionScript automatically converted the numeric design name into a number in scientific notation. In our case, this would be 0.1206712028 x 10^10. Unfortunately, this number was rounded to 0.120671203 x 10^10 because computers use floating point arithmetic to store numbers in scientific notation. This number would eventually be converted back to normal notation, but it was now 1206712030 because of the rounding error.
We fixed it by putting an ‘a’ in front of the timestamp, preventing the automatic conversion to a number. Not very elegant, but it works!