00001 /*************************************************************************** 00002 * Copyright (C) 2005-2011 LpzRobots development team * 00003 * Georg Martius <georg dot martius at web dot de> * 00004 * Frank Guettler <guettler at informatik dot uni-leipzig dot de * 00005 * Frank Hesse <frank at nld dot ds dot mpg dot de> * 00006 * Ralf Der <ralfder at mis dot mpg dot de> * 00007 * * 00008 * This program is free software; you can redistribute it and/or modify * 00009 * it under the terms of the GNU General Public License as published by * 00010 * the Free Software Foundation; either version 2 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * This program is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this program; if not, write to the * 00020 * Free Software Foundation, Inc., * 00021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00022 * * 00023 ***************************************************************************/ 00024 #ifndef __RANDOMGENERATOR_H 00025 #define __RANDOMGENERATOR_H 00026 00027 #include <stdlib.h> 00028 #ifndef _GNU_SOURCE 00029 #include "mac_drand48r.h" 00030 #endif 00031 00032 00033 /// random generator with 48bit integer arithmentic 00034 typedef struct _RandGen { 00035 _RandGen(){ 00036 init(::rand()); 00037 } 00038 void init(long int seedval){ 00039 srand48_r(seedval, &buffer); 00040 } 00041 /// returns a value in [0,1) 00042 double rand(){ 00043 double r; 00044 drand48_r(&buffer,&r); 00045 return r; 00046 } 00047 // See drand48_data structure: 00048 // struct drand48_data 00049 // { 00050 // unsigned short int __x[3]; /* Current state. */ 00051 // unsigned short int __old_x[3]; /* Old state. */ 00052 // unsigned short int __c; /* Additive const. in congruential formula. */ 00053 // unsigned short int __init; /* Flag for initializing. */ 00054 // unsigned long long int __a; /* Factor in congruential formula. */ 00055 // }; 00056 // 00057 // The function drand48_r writes too much data into __x. 00058 // I think it writes 16 bytes in the 8 byte sized array. 00059 // Therefore this destroys the call stack. 00060 // With a union and a char array of 24 Bytes we can force him 00061 // to write all elements in the structure to be aligned in memory 00062 // which is not ensured if you have a struct. 00063 // So the 16 bytes are written into __x and __old_x, the call stack is save. 00064 // This isn't the best way, but everything which isn't predictable 00065 // is in a random generator perfect. :o) 00066 union { 00067 struct drand48_data buffer; 00068 char dummy[24]; 00069 }; 00070 } RandGen; 00071 00072 00073 00074 00075 #endif