Possible math error in Blitzmax? (and speedtests)

BlitzMax Forums/BlitzMax Programming/Possible math error in Blitzmax? (and speedtests)

AdamRedwoods(Posted 2011) [#1]
I could be doing something wrong, but when I change the "local" to "global" it works.

blitzmax version 1.37



which outputs (correctly in debug, but not in release):



skidracer(Posted 2011) [#2]
Floats only have 7 digits of accuracy at the best of times, shouldn't you be using Doubles?


Warpy(Posted 2011) [#3]
Gosh, that is interesting! The problem's still there even if you change to Doubles.


Floyd(Posted 2011) [#4]
Brace yourself for some arcane details.

Floating point arithmetic is done in special 80-bit registers, regardless of whether the original number was single ( 32-bit ) or double ( 64-bit ). As long as the numbers remain in these registers they are being processed as 80-bit values. Whenever a value is stored from a register to memory it is rounded to a 32-bit or 64-bit approximation of that 80-bit value.

In a lengthy loop, such as this program uses, that can change results noticably. If all calculations are done without touching memory the results are more accurate than if intermediate results are stored/reloaded at each step in the loop. In Debug mode all such intermediate results are stored/reloaded. In Release mode they may or may not be, depending on available registers ( there are only eight of them ) and what kind of variables are involved. That's why the results here agree, except for the Local case.

As a separate issue note that the default floating point type for numeric literals is single precision. Thus 1.0000001 is single precision and you should use 1.0000001## to get double precision.

I changed all floats to doubles and ran the code in two forms. I used 1.0000001##, and also in the original from which defaults to #. Here are the results.



The most accurate form is visible at the top, with Release mode and ##. The fastest and most accurate is the "all register" calculation. It ends with 5021 while the others end with 3645.

As a final obscure statistical fact note that accumulated floating point errors tend to grow as the square root of the number of calculations: 100 times as much work means 10 times as much error, 10000 times the work gives 100 times the error...

We go through the loop 10^7 times. Sqr( 10^7 ) is around 3200 and so we expect to lose slightly more than three digits of accuracy. This is visible in the final digits of 5021 and 3645.


Okay, that may have been too much information. The short version is that Debug and Release results can differ, but not always. The accumulated difference will grow as the calculations get lengthier.

Although not on display here the differences can be large if values get stored into integers. For example 5.0001 will become 5 while 4.9999 will be 4.


Warpy(Posted 2011) [#5]
Eeesh, Floyd. Whenever I start feeling clever, you appear and dispel the notion.


AdamRedwoods(Posted 2011) [#6]
Very interesting, thanks for the info!