rand48.cpp

00001 /* -*- mode:C++; c-basic-offset:4 -*-
00002    Shore-MT -- Multi-threaded port of the SHORE storage manager
00003    
00004                        Copyright (c) 2007-2009
00005       Data Intensive Applications and Systems Labaratory (DIAS)
00006                Ecole Polytechnique Federale de Lausanne
00007    
00008                          All Rights Reserved.
00009    
00010    Permission to use, copy, modify and distribute this software and
00011    its documentation is hereby granted, provided that both the
00012    copyright notice and this permission notice appear in all copies of
00013    the software, derivative works or modified versions, and any
00014    portions thereof, and that both notices appear in supporting
00015    documentation.
00016    
00017    This code is distributed in the hope that it will be useful, but
00018    WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
00020    DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
00021    RESULTING FROM THE USE OF THIS SOFTWARE.
00022 */
00023 
00024 // -*- mode:c++; c-basic-offset:4 -*-
00025 /*<std-header orig-src='shore'>
00026 
00027  $Id: rand48.cpp,v 1.2 2010/05/26 01:20:21 nhall Exp $
00028 
00029 SHORE -- Scalable Heterogeneous Object REpository
00030 
00031 Copyright (c) 1994-99 Computer Sciences Department, University of
00032                       Wisconsin -- Madison
00033 All Rights Reserved.
00034 
00035 Permission to use, copy, modify and distribute this software and its
00036 documentation is hereby granted, provided that both the copyright
00037 notice and this permission notice appear in all copies of the
00038 software, derivative works or modified versions, and any portions
00039 thereof, and that both notices appear in supporting documentation.
00040 
00041 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00042 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00043 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00044 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00045 
00046 This software was developed with support by the Advanced Research
00047 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00048 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00049 Further funding for this work was provided by DARPA through
00050 Rome Research Laboratory Contract No. F30602-97-2-0247.
00051 
00052 */
00053 
00054 #include "w_defines.h"
00055 
00056 /*  -- do not edit anything above this line --   </std-header>*/
00057 
00058 #include "rand48.h"
00059 
00060 unsigned48_t rand48::_mask(unsigned48_t x)  const
00061 { 
00062     return x & 0xffffffffffffull; 
00063 }
00064 
00065 unsigned48_t rand48::_update() 
00066 {
00067     _state = _mask(_state*0x5deece66dull + 0xb);
00068     return _state;
00069 }
00070 
00071 double rand48::drand() 
00072 {
00073     /* In order to avoid the cost of multiple floating point ops we
00074        conjure up a double directly based on its bitwise
00075        representation:
00076 
00077        |S|EEEEEEEEEEE|FFFFFF....F|
00078            (11 bits)   (52 bits)
00079        
00080        where V = (-1)**S * 2**(E-1023) * 1.F (ie F is the fractional
00081        part of an implied 53-bit fixed-point number which can take
00082        values ranging from 1.000... to 1.111...). 
00083 
00084        The idea is to left-justify our random bits in the mantissa
00085        field (hence the << 4). Setting S=0 and E=0x3ff=1023 gives
00086        (-1)**0 * 2**(0x3ff-1023) * 1.F = 1.F, which is always
00087        normalized. We then subtract 1.0 to get the answer we actually
00088        want -- 0.F -- and make the hardware normalize it for us.
00089      */
00090     union { unsigned48_t n; double d; } u = {
00091     (0x3ffull << 52) | (_update() << 4)
00092     };
00093     return u.d-1.0;
00094 }
00095 
00096 /**\brief Used by testers.  
00097  *
00098  * Not operators because that would conflict
00099  * with the std:: operators for unsigned ints, alas.
00100  */
00101 void out(ofstream& o, const unsigned48_t& what)
00102 {
00103     /*
00104      * expect "........,........,........"
00105      * no spaces
00106      */
00107 
00108     union {
00109        unsigned48_t   seed;
00110        unsigned short dummy[sizeof(unsigned48_t)/sizeof(unsigned short)];
00111     } PUN;
00112     PUN.seed = what;
00113 
00114     o << 
00115         PUN.dummy[0] << "," << 
00116         PUN.dummy[1] << "," << 
00117         PUN.dummy[2] << "," << 
00118         PUN.dummy[3] << endl;
00119 }
00120 
00121 /**\brief Used by testers.  
00122  *
00123  * Not operators because that would conflict
00124  * with the std:: operators for unsigned ints, alas.
00125  */
00126 void in(ifstream& i, unsigned48_t& res)
00127 {
00128     /*
00129      * print "0x........,0x........,0x........"
00130      */
00131     union {
00132        unsigned48_t   seed;
00133        unsigned short dummy[sizeof(unsigned48_t)/sizeof(unsigned short)];
00134     } PUN ;
00135 
00136     char             comma = ',';
00137     unsigned         j=0;
00138 
00139     while( (comma == ',') && 
00140         (j < sizeof(PUN.dummy)/sizeof(unsigned short)) &&
00141         (i >>  PUN.dummy[j])
00142         ) {
00143 
00144             if(i.peek() == ',') i >> comma;
00145             j++;
00146     }
00147     if(j < sizeof(PUN.dummy)/sizeof(unsigned short) ) {
00148         // This actually sets the badbit:
00149         i.clear(ios::badbit|i.rdstate());
00150     }
00151     res = PUN.seed;
00152 }

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7