I'm no expert on the subject but I have read that computers often have 80 bits floating-point registers while a double in C++ often is 64 bits. For the computer to carry out various operations (+, -, *, /, etc.) it has to use the registers so first the 64 bit doubles has to be read from memory and stored in the 80 bit registers, then the result of the operation is computed, and at the end the result will be written back to memory where it will be stored as a 64 bit value, something like that.
Writing and reading from memory is relatively slow. If the computed value are going to be used again very soon it might be faster to just keep it in the register and avoid the write to and back from memory. The only problem with this is that result might not be exactly the same because when the floating point value is converted from 80 bits to 64 bits it loses precision and you will of course not get this precision back when converting the 64 bit back to a 80 bits. This means that carrying out two operations that in theory should give the same result might be slightly different because they have some small rounding error.
Volatile means that the variable can be changed at any time by the hardware so when you use it on a variable it will prevent a lot of optimizations. It also prevents the optimization mentioned above, so the result of the floating point operations has to be written to the variable's location in memory right away. For this to work correctly I think you would have to avoid subexpressions, and instead store every computation in a volatile variable.
1 2 3 4 5 6 7 8 9
|
volatile double a = 1;
volatile double b = 2;
// Here we can't be sure if the result of (a / b) will have 80 or 64 bit precision.
volatile double c1 = a / b * 2;
// Here we know m1 will be 64 bits.
volatile double m1 = a / b;
volatile double c2 = m1 * 2;
|
In the header file you can see that
#define INEXACT volatile has been commented out. Instead INEXACT is defined to nothing at all, which means that it will simply be ignored. The comment suggests the volatile hack is only needed on some computer architectures, but as I said I'm no expert on this so I don't know how much of a problem this is.
I also found this page
https://gcc.gnu.org/wiki/x87note which I find a bit worrying because it suggests not even simple assignments like a = b; can be trusted with a == b giving true.