|
From: Gordon K. <kin...@us...> - 2004-05-12 10:03:40
|
Update of /cvsroot/teem/teem/src/air In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18464 Modified Files: 754.c GNUmakefile air.h miscAir.c Added Files: rand48.c Log Message: adapted/simplified the drand48() implementation from glibc-2.3, in new functions airDrand48(), including a re-entrant version airDrand48_r(). This became an issue as soon as echo become genuinely multi-threaded Index: 754.c =================================================================== RCS file: /cvsroot/teem/teem/src/air/754.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** 754.c 7 Jan 2004 15:34:27 -0000 1.15 --- 754.c 12 May 2004 10:03:26 -0000 1.16 *************** *** 20,23 **** --- 20,24 ---- #include "air.h" + #include "privateAir.h" #include <teemEndian.h> #include <teemQnanhibit.h> *************** *** 38,107 **** #endif - /* - ** _airFloat, _airDouble - ** - ** these unions facilitate converting amonst - ** i: unsigned integral type - ** c: (sign,exp,frac) triples of unsigned integral components - ** v: the floating point numbers these bit-patterns represent - */ - typedef union { - unsigned int i; - struct { - #if TEEM_ENDIAN == 1234 - unsigned int frac : 23; - unsigned int exp : 8; - unsigned int sign : 1; - #else - unsigned int sign : 1; - unsigned int exp : 8; - unsigned int frac : 23; - #endif - } c; - float v; - } _airFloat; - - typedef union { - airULLong i; - #if TEEM_BIGBITFIELD == 1 - /* #ifndef __sparc */ - struct { - # if TEEM_ENDIAN == 1234 - airULLong frac : 52; - unsigned int exp : 11; - unsigned int sign : 1; - # else - unsigned int sign : 1; - unsigned int exp : 11; - airULLong frac : 52; - # endif - } c; - #endif - /* these next two members are used for printing in airFPFprintf_d */ - struct { /* access to whole double as two unsigned ints */ - #if TEEM_ENDIAN == 1234 - unsigned int half0 : 32; - unsigned int half1 : 32; - #else - unsigned int half1 : 32; - unsigned int half0 : 32; - #endif - } h; - struct { /* access to fraction with two unsigned ints */ - #if TEEM_ENDIAN == 1234 - unsigned int frac0 : 32; - unsigned int frac1 : 20; - unsigned int exp : 11; - unsigned int sign : 1; - #else - unsigned int sign : 1; - unsigned int exp : 11; - unsigned int frac1 : 20; - unsigned int frac0 : 32; - #endif - } c2; - double v; - } _airDouble; - /* ** The hex numbers in braces are examples of C's "initial member of a union" --- 39,42 ---- Index: miscAir.c =================================================================== RCS file: /cvsroot/teem/teem/src/air/miscAir.c,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** miscAir.c 22 Apr 2004 10:12:45 -0000 1.24 --- miscAir.c 12 May 2004 10:03:27 -0000 1.25 *************** *** 259,292 **** /* - ******** airSrand() - ** - ** uses clock to seed srand() - */ - void - airSrand(void) { - - srand((unsigned int)airTime()); - } - - /* - ******** airRand() - ** - ** returns double in range [0.0,1.0) - */ - double - airRand(void) { - double val, sc = 1.0/(RAND_MAX+1.0); - - val = sc*rand(); - - /* repeat as needed */ - val = sc*(val + rand()); - val = sc*(val + rand()); - val = sc*(val + rand()); - - return val; - } - - /* ******** airRandInt ** --- 259,262 ---- *************** *** 297,301 **** int i; ! AIR_INDEX(0.0, airRand(), 1.0, N, i); i = AIR_CLAMP(0, i, N-1); return i; --- 267,271 ---- int i; ! AIR_INDEX(0.0, airDrand48(), 1.0, N, i); i = AIR_CLAMP(0, i, N-1); return i; Index: air.h =================================================================== RCS file: /cvsroot/teem/teem/src/air/air.h,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** air.h 13 Mar 2004 20:03:08 -0000 1.40 --- air.h 12 May 2004 10:03:27 -0000 1.41 *************** *** 300,303 **** --- 300,315 ---- TEEM_API int airExists_d(double d); + typedef struct { + airULLong a; /* Factor in congruential formula. */ + unsigned short c, /* Additive const. in congruential formula. */ + x0, x1, x2; /* Current state. */ + } airDrand48State; + /* rand48.c */ + TEEM_API airDrand48State *airDrand48StateGlobal; + TEEM_API void airSrand48_r(airDrand48State *state, int seed); + TEEM_API double airDrand48_r(airDrand48State *state); + TEEM_API void airSrand48(int seed); + TEEM_API double airDrand48(); + /* ******** airType *************** *** 395,400 **** /* ---- BEGIN non-NrrdIO */ TEEM_API const char airMyFmt_size_t[]; - TEEM_API void airSrand(void); - TEEM_API double airRand(void); TEEM_API int airRandInt(int N); TEEM_API void airShuffle(int *buff, int N, int perm); --- 407,410 ---- --- NEW FILE: rand48.c --- /* teem: Gordon Kindlmann's research software Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* ** The contents of this file were derived from the *rand48*.c files ** from glibc-2.3/stdlib, which is distributed under the LGPL that ** governs the distribution of Teem. */ #include "air.h" #include "privateAir.h" airDrand48State _airDrand48StateGlobal = { AIR_ULLONG(0x5deece66d), /* a */ 0xb, /* c */ 0x330e, 0, 0 /* x0, x1, x2 */ }; airDrand48State * airDrand48StateGlobal = &_airDrand48StateGlobal; void _airDrand48Iterate(airDrand48State *state) { airULLong X, result; X = ((airULLong)state->x2 << 32 | (unsigned)state->x1 << 16 | state->x0); result = X*state->a + state->c; state->x0 = result & 0xffff; state->x1 = (result >> 16) & 0xffff; state->x2 = (result >> 32) & 0xffff; return; } void airSrand48_r(airDrand48State *state, int seed) { state->x0 = 0x330e; state->x1 = seed & 0xffff; state->x2 = seed >> 16; state->c = 0xb; state->a = AIR_ULLONG(0x5deece66d); return; } void airSrand48(int seed) { airSrand48_r(airDrand48StateGlobal, seed); return; } double airDrand48_r(airDrand48State *state) { _airDouble temp; _airDrand48Iterate(state); temp.v = 1.0; temp.c2.frac1 = (state->x2 << 4) | (state->x1 >> 12); temp.c2.frac0 = ((state->x1 & 0xfff) << 20) | (state->x0 << 4); return temp.v - 1.0; } double airDrand48() { return airDrand48_r(airDrand48StateGlobal); } Index: GNUmakefile =================================================================== RCS file: /cvsroot/teem/teem/src/air/GNUmakefile,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** GNUmakefile 7 Jan 2004 15:34:27 -0000 1.12 --- GNUmakefile 12 May 2004 10:03:27 -0000 1.13 *************** *** 46,53 **** $(L).NEED = $(L).PUBLIC_HEADERS = air.h ! $(L).OBJS = 754.o array.o miscAir.o parseAir.o endianAir.o \ dio.o mop.o enum.o sane.o string.o threadAir.o $(L).TESTS = test/floatprint test/doubleprint test/tok \ ! test/tmop test/tline test/fp $(L).NEED_ENDIAN = true --- 46,54 ---- $(L).NEED = $(L).PUBLIC_HEADERS = air.h ! $(L).PRIVATE_HEADERS = privateAir.h ! $(L).OBJS = 754.o rand48.o array.o miscAir.o parseAir.o endianAir.o \ dio.o mop.o enum.o sane.o string.o threadAir.o $(L).TESTS = test/floatprint test/doubleprint test/tok \ ! test/tmop test/tline test/fp test/trand $(L).NEED_ENDIAN = true |