1.25 Unions.
main endp
Thef()function is almost understandable. However, what is interesting is that GCC was able to calcu-
late the result off(1.234)during compilation despite all this hodge-podge with the structure fields and
prepared this argument toprintf()as precalculated at compile time!
1.24.7 Exercises.
1.25 Unions
C/C++unionis mostly used for interpreting a variable (or memory block) of one data type as a variable
of another data type.
1.25.1 Pseudo-random number generator example
If we need float random numbers between 0 and 1, the simplest thing is to use aPRNGlike the Mersenne
twister. It produces random unsigned 32-bit values (in other words, it produces random 32 bits). Then we
can transform this value tofloatand then divide it byRAND_MAX(0xFFFFFFFFin our case)—we getting a
value in the 0..1 interval.
But as we know, division is slow. Also, we would like to issue as few FPU operations as possible. Can we
get rid of the division?
Let’s recall what a floating point number consists of: sign bit, significand bits and exponent bits. We just
have to store random bits in all significand bits to get a random float number!
Theexponentcannotbezero(thefloatingnumberisdenormalizedinthiscase),sowearestoring0b01111111
to exponent—this means that the exponent is 1. Then we filling the significand with random bits, set the
sign bit to 0 (which means a positive number) and voilà. The generated numbers is to be between 1 and
2, so we must also subtract 1.
A very simple linear congruential random numbers generator is used in my example^168 , it produces 32-bit
numbers. ThePRNGis initialized with the current time in UNIX timestamp format.
Here we represent thefloattype as anunion—it is the C/C++ construction that enables us to interpret a
piece of memory as different types. In our case, we are able to create a variable of typeunionand then
access to it as it isfloator as it isuint32_t. It can be said, it is just a hack. A dirty one.
The integerPRNGcode is the same as we already considered:1.23 on page 338. So this code in compiled
form is omitted.
#include <stdio.h>
#include <stdint.h>
#include <time.h>
// integer PRNG definitions, data and routines:
// constants from the Numerical Recipes book
const uint32_t RNG_a=1664525;
const uint32_t RNG_c=1013904223;
uint32_t RNG_state; // global variable
void my_srand(uint32_t i)
{
RNG_state=i;
};
uint32_t my_rand()
{
(^168) the idea was taken from:http://go.yurichev.com/17308