[Most of my readers will not understand the following, but the mathematicians will love it]
A couple of years ago, a mathematician friend told me some problems he had about optimizing a program (maths calculations), asking me for suggestions. I answered with some ideas, but then he asked me about the double format, the way the computer stores a double variable, with its separated sign, mantissa and exponent (actually, IEEE 754). He was pretending to manipulate directly those parts, to improve the calculation’s speed. I didn’t help him in a clear way.
In the last few months I’ve been taking part in some programming contests, on TopCoder. Today one of the problems was really boring but at the same time really interesting. In brief, it says that the division is a computationally expensive operation, except if the divisor is a power of 2 (then you can use just bit shifts to do so). The statement asks to program a division, approximating the result using a series of divisions by powers of 2.
I tried to use bit shifts and bit masks to get the exponent of a double (keeping in mind the double binary format), but I discovered that C++ (as C) doesn’t allow bit operations with doubles.
Nevertheless later I asked in the forums, and got an interesting idea. Using an “union“ you bind two or more variables, sharing the same memory position. That way you can manipulate the value in memory from different angles.
Here is an example in pure C:
#include <stdio.h> struct Double{ unsigned long long mantissa : 52; /* 52 bits */ unsigned exponent : 11; /* 11 bits */ unsigned sign : 1; /* 1 bit: 0 is positive, 1 is negative */ }; int main(){ union{ double value; Double parts; } u; u.value = 3.1451592; /* Direct manipulation */ u.parts.exponent++; /* Multiply by 2 */ u.parts.sign = 1; /* set negative */ printf("%f",u.value); /* -6.28... */ }