|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: R T
Length: 2014 (0x7de)
Types: TextFile
Names: »RNG.cc«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
└─⟦cc8755de2⟧ »./libg++-1.36.1.tar.Z«
└─⟦23757c458⟧
└─⟦this⟧ »libg++/src/RNG.cc«
#include <values.h>
#include <assert.h>
#include <builtin.h>
#include <RNG.h>
//
// The scale constant is 2^-31. It is used to scale a 31 bit
// long to a double.
//
//static const double randomDoubleScaleConstant = 4.656612873077392578125e-10;
//static const float randomFloatScaleConstant = 4.656612873077392578125e-10;
static char initialized = 0;
RNG::RNG()
{
if (!initialized)
{
assert (sizeof(double) == 2 * sizeof(unsigned long));
//
// The following is a hack that I attribute to
// Andres Nowatzyk at CMU. The intent of the loop
// is to form the smallest number 0 <= x < 1.0,
// which is then used as a mask for two longwords.
// this gives us a fast way way to produce double
// precision numbers from longwords.
//
// I know that this works for IEEE and VAX floating
// point representations.
//
// A further complication is that gnu C will blow
// the following loop, unless compiled with -ffloat-store,
// because it uses extended representations for some of
// of the comparisons. Thus, we have the following hack.
// If we could specify #pragma optimize, we wouldn't need this.
//
PrivateRNGDoubleType t;
PrivateRNGSingleType s;
#if _IEEE == 1
t.d = 1.5;
if ( t.u[1] == 0 ) { // sun word order?
t.u[0] = 0x3fffffff;
t.u[1] = 0xffffffff;
}
else {
t.u[0] = 0xffffffff; // encore word order?
t.u[1] = 0x3fffffff;
}
s.u = 0x3fffffff;
#else
double x = 1.0;
double y = 0.5;
do { // find largest fp-number < 2.0
t.d = x;
x += y;
y *= 0.5;
} while (x != t.d && x < 2.0);
float xx = 1.0;
float yy = 0.5;
do { // find largest fp-number < 2.0
s.s = xx;
xx += yy;
yy *= 0.5;
} while (xx != s.s && xx < 2.0);
#endif
// set doubleMantissa to 1 for each doubleMantissa bit
doubleMantissa.d = 1.0;
doubleMantissa.u[0] ^= t.u[0];
doubleMantissa.u[1] ^= t.u[1];
// set singleMantissa to 1 for each singleMantissa bit
singleMantissa.s = 1.0;
singleMantissa.u ^= s.u;
initialized = 1;
}
}