Also note that when dividing floating point, we divide the dividend's mantissa by the divisor's mantissa, then adjust the exponents by subtracting the divisor's exponent from the dividend's. And of course, sign is adjusted to match the combination of the sign's of the dividend and divisor (I believe XOR will perform that correctly).

So whether the numbers are small or large makes no difference to the actual precision of the result. Obviously, double having more bits meaning a more precise result can be produced.

Multiply is essentially the same, except of course it multiplies the two components mantissa and adds the exponents.

Much more sensitive to inputs is the add and subtract, since the two numbers have to be normalized (mantissas need to be aligned so that the "decimal point inside the mantissa" is in the same place), so adding or subtracting numbers that have a huge difference in magnitude will loose precision. Say we have 5 digits to work with (unrealistic but simple):

Code:

float a = 123.45; -> 1.2345E2
float b = 0.102; -> 1E-3
// align b to a -> b = 0.0010E2: the last 2 falls off the edge.
a -= b;
// a = 123.35, not 123.348

The calculation is inprecise because of the adjustment of the numbers.

Ths becomes most noticable when you add a small number from a large number, then subtract the original large number, e.g.:

Code:

float a = 2.0f;
float b = 0.00001f;
a += b;
a -= 2.0f;

if the compiler rounds that on each step [which it may not do], you may find that a is zero, rather than a small number (if there's enough zero's in the beginning of b - it may not be quite enough as it is above) .

Also note that Magos's example showing that the intermediate calculation is done in double precision only applies to SOME floating point processors - x87 for example always calculates at full precision, then rounds it to the precision requested. But other processors/compilers may choose to perform the intermediate calculation in float precision.

--

Mats