/home/coin/SVN-release/CoinAll-1.1.0/CoinUtils/src/CoinHelperFunctions.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 #ifndef CoinHelperFunctions_H
00005 #define CoinHelperFunctions_H
00006 #if defined(_MSC_VER)
00007 #  include <direct.h>
00008 #  define getcwd _getcwd
00009 #else
00010 #  include <unistd.h>
00011 #endif
00012 
00013 #include <cstdlib>
00014 #include <cstdio>
00015 #include "CoinError.hpp"
00016 #include "CoinFinite.hpp"
00017 //#############################################################################
00018 
00024 template <class T> inline void
00025 CoinCopyN(register const T* from, const int size, register T* to)
00026 {
00027     if (size == 0 || from == to)
00028         return;
00029 
00030     if (size < 0)
00031         throw CoinError("trying to copy negative number of entries",
00032                         "CoinCopyN", "");
00033 
00034     register int n = (size + 7) / 8;
00035     if (to > from) {
00036         register const T* downfrom = from + size;
00037         register T* downto = to + size;
00038         // Use Duff's device to copy
00039         switch (size % 8) {
00040         case 0: do{     *--downto = *--downfrom;
00041         case 7:         *--downto = *--downfrom;
00042         case 6:         *--downto = *--downfrom;
00043         case 5:         *--downto = *--downfrom;
00044         case 4:         *--downto = *--downfrom;
00045         case 3:         *--downto = *--downfrom;
00046         case 2:         *--downto = *--downfrom;
00047         case 1:         *--downto = *--downfrom;
00048         }while(--n>0);
00049         }
00050     } else {
00051         // Use Duff's device to copy
00052         --from;
00053         --to;
00054         switch (size % 8) {
00055         case 0: do{     *++to = *++from;
00056         case 7:         *++to = *++from;
00057         case 6:         *++to = *++from;
00058         case 5:         *++to = *++from;
00059         case 4:         *++to = *++from;
00060         case 3:         *++to = *++from;
00061         case 2:         *++to = *++from;
00062         case 1:         *++to = *++from;
00063         }while(--n>0);
00064         }
00065     }
00066 }
00067 
00068 //-----------------------------------------------------------------------------
00069 
00074 template <class T> inline void
00075 CoinCopy(register const T* first, register const T* last, register T* to)
00076 {
00077     CoinCopyN(first, last - first, to);
00078 }
00079 
00080 //-----------------------------------------------------------------------------
00081 
00089 template <class T> inline void
00090 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00091 {
00092 #ifndef _MSC_VER
00093     if (size == 0 || from == to)
00094         return;
00095 
00096     if (size < 0)
00097         throw CoinError("trying to copy negative number of entries",
00098                         "CoinDisjointCopyN", "");
00099 
00100 #if 0
00101     /* There is no point to do this test. If to and from are from different
00102        blocks then dist is undefined, so this can crash correct code. It's
00103        better to trust the user that the arrays are really disjoint. */
00104     const long dist = to - from;
00105     if (-size < dist && dist < size)
00106         throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00107 #endif
00108 
00109     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00110         to[0] = from[0];
00111         to[1] = from[1];
00112         to[2] = from[2];
00113         to[3] = from[3];
00114         to[4] = from[4];
00115         to[5] = from[5];
00116         to[6] = from[6];
00117         to[7] = from[7];
00118     }
00119     switch (size % 8) {
00120     case 7: to[6] = from[6];
00121     case 6: to[5] = from[5];
00122     case 5: to[4] = from[4];
00123     case 4: to[3] = from[3];
00124     case 3: to[2] = from[2];
00125     case 2: to[1] = from[1];
00126     case 1: to[0] = from[0];
00127     case 0: break;
00128     }
00129 #else
00130     CoinCopyN(from, size, to);
00131 #endif
00132 }
00133 
00134 //-----------------------------------------------------------------------------
00135 
00140 template <class T> inline void
00141 CoinDisjointCopy(register const T* first, register const T* last,
00142                  register T* to)
00143 {
00144     CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00145 }
00146 
00147 //-----------------------------------------------------------------------------
00148 
00153 template <class T> inline T*
00154 CoinCopyOfArray( const T * array, const int size)
00155 {
00156     if (array) {
00157         T * arrayNew = new T[size];
00158         memcpy(arrayNew,array,size*sizeof(T));
00159         return arrayNew;
00160     } else {
00161         return NULL;
00162     }
00163 }
00164 
00165 
00170 template <class T> inline T*
00171 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00172 {
00173     if (array) {
00174         T * arrayNew = new T[size];
00175         assert (copySize<=size);
00176         memcpy(arrayNew,array,copySize*sizeof(T));
00177         return arrayNew;
00178     } else {
00179         return NULL;
00180     }
00181 }
00182 
00187 template <class T> inline T*
00188 CoinCopyOfArray( const T * array, const int size, T value)
00189 {
00190     T * arrayNew = new T[size];
00191     if (array) {
00192         memcpy(arrayNew,array,size*sizeof(T));
00193     } else {
00194         int i;
00195         for (i=0;i<size;i++) 
00196             arrayNew[i] = value;
00197     }
00198     return arrayNew;
00199 }
00200 
00201 
00206 template <class T> inline T*
00207 CoinCopyOfArrayOrZero( const T * array , const int size)
00208 {
00209     T * arrayNew = new T[size];
00210     if (array) {
00211         memcpy(arrayNew,array,size*sizeof(T));
00212     } else {
00213         memset(arrayNew,0,size*sizeof(T));
00214     }
00215     return arrayNew;
00216 }
00217 
00218 
00219 //-----------------------------------------------------------------------------
00220 
00228 template <class T> inline void
00229 CoinMemcpyN(register const T* from, const int size, register T* to)
00230 {
00231 #ifndef _MSC_VER
00232 #ifdef USE_MEMCPY
00233     // Use memcpy - seems a lot faster on Intel with gcc
00234 #ifndef NDEBUG
00235     // Some debug so check
00236     if (size < 0)
00237         throw CoinError("trying to copy negative number of entries",
00238                         "CoinMemcpyN", "");
00239   
00240 #if 0
00241     /* There is no point to do this test. If to and from are from different
00242        blocks then dist is undefined, so this can crash correct code. It's
00243        better to trust the user that the arrays are really disjoint. */
00244     const long dist = to - from;
00245     if (-size < dist && dist < size)
00246         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00247 #endif
00248 #endif
00249     memcpy(to,from,size*sizeof(T));
00250 #else
00251     if (size == 0 || from == to)
00252         return;
00253 
00254     if (size < 0)
00255         throw CoinError("trying to copy negative number of entries",
00256                         "CoinMemcpyN", "");
00257 
00258 #if 0
00259     /* There is no point to do this test. If to and from are from different
00260        blocks then dist is undefined, so this can crash correct code. It's
00261        better to trust the user that the arrays are really disjoint. */
00262     const long dist = to - from;
00263     if (-size < dist && dist < size)
00264         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00265 #endif
00266 
00267     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00268         to[0] = from[0];
00269         to[1] = from[1];
00270         to[2] = from[2];
00271         to[3] = from[3];
00272         to[4] = from[4];
00273         to[5] = from[5];
00274         to[6] = from[6];
00275         to[7] = from[7];
00276     }
00277     switch (size % 8) {
00278     case 7: to[6] = from[6];
00279     case 6: to[5] = from[5];
00280     case 5: to[4] = from[4];
00281     case 4: to[3] = from[3];
00282     case 3: to[2] = from[2];
00283     case 2: to[1] = from[1];
00284     case 1: to[0] = from[0];
00285     case 0: break;
00286     }
00287 #endif
00288 #else
00289     CoinCopyN(from, size, to);
00290 #endif
00291 }
00292 
00293 //-----------------------------------------------------------------------------
00294 
00299 template <class T> inline void
00300 CoinMemcpy(register const T* first, register const T* last,
00301            register T* to)
00302 {
00303     CoinMemcpyN(first, static_cast<int>(last - first), to);
00304 }
00305 
00306 //#############################################################################
00307 
00314 template <class T> inline void
00315 CoinFillN(register T* to, const int size, register const T value)
00316 {
00317     if (size == 0)
00318         return;
00319 
00320     if (size < 0)
00321         throw CoinError("trying to fill negative number of entries",
00322                         "CoinFillN", "");
00323 
00324 #if 1
00325     for (register int n = size / 8; n > 0; --n, to += 8) {
00326         to[0] = value;
00327         to[1] = value;
00328         to[2] = value;
00329         to[3] = value;
00330         to[4] = value;
00331         to[5] = value;
00332         to[6] = value;
00333         to[7] = value;
00334     }
00335     switch (size % 8) {
00336     case 7: to[6] = value;
00337     case 6: to[5] = value;
00338     case 5: to[4] = value;
00339     case 4: to[3] = value;
00340     case 3: to[2] = value;
00341     case 2: to[1] = value;
00342     case 1: to[0] = value;
00343     case 0: break;
00344     }
00345 #else
00346     // Use Duff's device to fill
00347     register int n = (size + 7) / 8;
00348     --to;
00349     switch (size % 8) {
00350     case 0: do{     *++to = value;
00351     case 7:         *++to = value;
00352     case 6:         *++to = value;
00353     case 5:         *++to = value;
00354     case 4:         *++to = value;
00355     case 3:         *++to = value;
00356     case 2:         *++to = value;
00357     case 1:         *++to = value;
00358     }while(--n>0);
00359     }
00360 #endif
00361 }
00362 
00363 //-----------------------------------------------------------------------------
00364 
00368 template <class T> inline void
00369 CoinFill(register T* first, register T* last, const T value)
00370 {
00371     CoinFillN(first, last - first, value);
00372 }
00373 
00374 //#############################################################################
00375 
00382 template <class T> inline void
00383 CoinZeroN(register T* to, const int size)
00384 {
00385 #ifdef USE_MEMCPY
00386     // Use memset - seems faster on Intel with gcc
00387 #ifndef NDEBUG
00388     // Some debug so check
00389     if (size < 0)
00390         throw CoinError("trying to fill negative number of entries",
00391                         "CoinZeroN", "");
00392 #endif
00393     memset(to,0,size*sizeof(T));
00394 #else
00395     if (size == 0)
00396         return;
00397 
00398     if (size < 0)
00399         throw CoinError("trying to fill negative number of entries",
00400                         "CoinZeroN", "");
00401 #if 1
00402     for (register int n = size / 8; n > 0; --n, to += 8) {
00403         to[0] = 0;
00404         to[1] = 0;
00405         to[2] = 0;
00406         to[3] = 0;
00407         to[4] = 0;
00408         to[5] = 0;
00409         to[6] = 0;
00410         to[7] = 0;
00411     }
00412     switch (size % 8) {
00413     case 7: to[6] = 0;
00414     case 6: to[5] = 0;
00415     case 5: to[4] = 0;
00416     case 4: to[3] = 0;
00417     case 3: to[2] = 0;
00418     case 2: to[1] = 0;
00419     case 1: to[0] = 0;
00420     case 0: break;
00421     }
00422 #else
00423     // Use Duff's device to fill
00424     register int n = (size + 7) / 8;
00425     --to;
00426     switch (size % 8) {
00427     case 0: do{     *++to = 0;
00428     case 7:         *++to = 0;
00429     case 6:         *++to = 0;
00430     case 5:         *++to = 0;
00431     case 4:         *++to = 0;
00432     case 3:         *++to = 0;
00433     case 2:         *++to = 0;
00434     case 1:         *++to = 0;
00435     }while(--n>0);
00436     }
00437 #endif
00438 #endif
00439 }
00441 inline void
00442 CoinCheckDoubleZero(double * to, const int size)
00443 {
00444     int n=0;
00445     for (int j=0;j<size;j++) {
00446         if (to[j]) 
00447             n++;
00448     }
00449     if (n) {
00450         printf("array of length %d should be zero has %d nonzero\n",size,n);
00451     }
00452 }
00454 inline void
00455 CoinCheckIntZero(int * to, const int size)
00456 {
00457     int n=0;
00458     for (int j=0;j<size;j++) {
00459         if (to[j]) 
00460             n++;
00461     }
00462     if (n) {
00463         printf("array of length %d should be zero has %d nonzero\n",size,n);
00464     }
00465 }
00466 
00467 //-----------------------------------------------------------------------------
00468 
00472 template <class T> inline void
00473 CoinZero(register T* first, register T* last)
00474 {
00475     CoinZeroN(first, last - first);
00476 }
00477 
00478 //#############################################################################
00479 
00483 template <class T> inline T
00484 CoinMax(register const T x1, register const T x2)
00485 {
00486     return (x1 > x2) ? x1 : x2;
00487 }
00488 
00489 //-----------------------------------------------------------------------------
00490 
00494 template <class T> inline T
00495 CoinMin(register const T x1, register const T x2)
00496 {
00497     return (x1 < x2) ? x1 : x2;
00498 }
00499 
00500 //-----------------------------------------------------------------------------
00501 
00505 template <class T> inline T
00506 CoinAbs(const T value)
00507 {
00508     return value<0 ? -value : value;
00509 }
00510 
00511 //#############################################################################
00512 
00516 template <class T> inline bool
00517 CoinIsSorted(register const T* first, const int size)
00518 {
00519     if (size == 0)
00520         return true;
00521 
00522     if (size < 0)
00523         throw CoinError("negative number of entries", "CoinIsSorted", "");
00524 
00525 #if 1
00526     // size1 is the number of comparisons to be made
00527     const int size1 = size  - 1;
00528     for (register int n = size1 / 8; n > 0; --n, first += 8) {
00529         if (first[8] < first[7]) return false;
00530         if (first[7] < first[6]) return false;
00531         if (first[6] < first[5]) return false;
00532         if (first[5] < first[4]) return false;
00533         if (first[4] < first[3]) return false;
00534         if (first[3] < first[2]) return false;
00535         if (first[2] < first[1]) return false;
00536         if (first[1] < first[0]) return false;
00537     }
00538 
00539     switch (size1 % 8) {
00540     case 7: if (first[7] < first[6]) return false;
00541     case 6: if (first[6] < first[5]) return false;
00542     case 5: if (first[5] < first[4]) return false;
00543     case 4: if (first[4] < first[3]) return false;
00544     case 3: if (first[3] < first[2]) return false;
00545     case 2: if (first[2] < first[1]) return false;
00546     case 1: if (first[1] < first[0]) return false;
00547     case 0: break;
00548     }
00549 #else
00550     register const T* next = first;
00551     register const T* last = first + size;
00552     for (++next; next != last; first = next, ++next)
00553         if (*next < *first)
00554             return false;
00555 #endif   
00556     return true;
00557 }
00558 
00559 //-----------------------------------------------------------------------------
00560 
00564 template <class T> inline bool
00565 CoinIsSorted(register const T* first, register const T* last)
00566 {
00567     return CoinIsSorted(first, static_cast<int>(last - first));
00568 }
00569 
00570 //#############################################################################
00571 
00575 template <class T> inline void
00576 CoinIotaN(register T* first, const int size, register T init)
00577 {
00578     if (size == 0)
00579         return;
00580 
00581     if (size < 0)
00582         throw CoinError("negative number of entries", "CoinIotaN", "");
00583 
00584 #if 1
00585     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00586         first[0] = init;
00587         first[1] = init + 1;
00588         first[2] = init + 2;
00589         first[3] = init + 3;
00590         first[4] = init + 4;
00591         first[5] = init + 5;
00592         first[6] = init + 6;
00593         first[7] = init + 7;
00594     }
00595     switch (size % 8) {
00596     case 7: first[6] = init + 6;
00597     case 6: first[5] = init + 5;
00598     case 5: first[4] = init + 4;
00599     case 4: first[3] = init + 3;
00600     case 3: first[2] = init + 2;
00601     case 2: first[1] = init + 1;
00602     case 1: first[0] = init;
00603     case 0: break;
00604     }
00605 #else
00606     // Use Duff's device to fill
00607     register int n = (size + 7) / 8;
00608     --first;
00609     --init;
00610     switch (size % 8) {
00611     case 0: do{     *++first = ++init;
00612     case 7:         *++first = ++init;
00613     case 6:         *++first = ++init;
00614     case 5:         *++first = ++init;
00615     case 4:         *++first = ++init;
00616     case 3:         *++first = ++init;
00617     case 2:         *++first = ++init;
00618     case 1:         *++first = ++init;
00619     }while(--n>0);
00620     }
00621 #endif
00622 }
00623 
00624 //-----------------------------------------------------------------------------
00625 
00629 template <class T> inline void
00630 CoinIota(T* first, const T* last, T init)
00631 {
00632     CoinIotaN(first, last-first, init);
00633 }
00634 
00635 //#############################################################################
00636 
00642 template <class T> inline T *
00643 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00644                            const int * firstDelPos, const int * lastDelPos)
00645 {
00646     int delNum = lastDelPos - firstDelPos;
00647     if (delNum == 0)
00648         return arrayLast;
00649 
00650     if (delNum < 0)
00651         throw CoinError("trying to delete negative number of entries",
00652                         "CoinDeleteEntriesFromArray", "");
00653 
00654     int * delSortedPos = NULL;
00655     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00656            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00657         // the positions of the to be deleted is either not sorted or not unique
00658         delSortedPos = new int[delNum];
00659         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00660         std::sort(delSortedPos, delSortedPos + delNum);
00661         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00662     }
00663     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00664 
00665     const int last = delNum - 1;
00666     int size = delSorted[0];
00667     for (int i = 0; i < last; ++i) {
00668         const int copyFirst = delSorted[i] + 1;
00669         const int copyLast = delSorted[i+1];
00670         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00671                  arrayFirst + size);
00672         size += copyLast - copyFirst;
00673     }
00674     const int copyFirst = delSorted[last] + 1;
00675     const int copyLast = arrayLast - arrayFirst;
00676     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00677              arrayFirst + size);
00678     size += copyLast - copyFirst;
00679 
00680     if (delSortedPos)
00681         delete[] delSortedPos;
00682 
00683     return arrayFirst + size;
00684 }
00685 
00686 //#############################################################################
00687 
00688 #define COIN_OWN_RANDOM_32
00689 
00690 #if defined COIN_OWN_RANDOM_32
00691 /* Thanks to Stefano Gliozzi for providing an operating system
00692    independent random number generator.  */
00693 
00694 // linear congruential generator. given the seed, the generated numbers are  
00695 // always the same regardless the (32 bit) architecture. This allows to 
00696 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
00697 // getting in most cases the same optimization path. 
00699 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00700 {
00701   static unsigned int last = 123456;
00702   if (isSeed) { 
00703     last = seed;
00704   } else {
00705     last = 1664525*last+1013904223;
00706     return (((double) last)/4294967296.0);
00707   }
00708   return(0.0);
00709 }
00711 inline void CoinSeedRandom(int iseed)
00712 {
00713   CoinDrand48(true, iseed);
00714 }
00715 
00716 #else // COIN_OWN_RANDOM_32
00717 
00718 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00719 
00720 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00721 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00722 
00723 #else
00724 
00725 inline double CoinDrand48() { return drand48(); }
00726 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00727 
00728 #endif
00729 
00730 #endif // COIN_OWN_RANDOM_32
00731 
00732 //#############################################################################
00733 
00736 inline char CoinFindDirSeparator()
00737 {
00738     int size = 1000;
00739     char* buf = 0;
00740     while (true) {
00741         buf = new char[size];
00742         if (getcwd(buf, size))
00743             break;
00744         delete[] buf;
00745         buf = 0;
00746         size = 2*size;
00747     }
00748     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we 
00749     // assume it's dos and the dirsep is '\'
00750     char dirsep = buf[0] == '/' ? '/' : '\\';
00751     delete[] buf;
00752     return dirsep;
00753 }
00754 //#############################################################################
00755 
00756 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00757                            const size_t len)
00758 {
00759     for (size_t i = 0; i < len; ++i) {
00760         if (s0[i] == 0) {
00761             return s1[i] == 0 ? 0 : -1;
00762         }
00763         if (s1[i] == 0) {
00764             return 1;
00765         }
00766         const int c0 = tolower(s0[i]);
00767         const int c1 = tolower(s1[i]);
00768         if (c0 < c1)
00769             return -1;
00770         if (c0 > c1)
00771             return 1;
00772     }
00773     return 0;
00774 }
00775 
00776 //#############################################################################
00777 
00779 template <class T> inline void CoinSwap (T &x, T &y)
00780 {
00781     T t = x;
00782     x = y;
00783     y = t;
00784 }
00785 
00786 //#############################################################################
00787 
00792 template <class T> inline int
00793 CoinToFile( const T* array, int size, FILE * fp)
00794 {
00795     int numberWritten;
00796     if (array&&size) {
00797         numberWritten = fwrite(&size,sizeof(int),1,fp);
00798         if (numberWritten!=1)
00799             return 1;
00800         numberWritten = fwrite(array,sizeof(T),size,fp);
00801         if (numberWritten!=size)
00802             return 1;
00803     } else {
00804         size = 0;
00805         numberWritten = fwrite(&size,sizeof(int),1,fp);
00806         if (numberWritten!=1)
00807             return 1;
00808     }
00809     return 0;
00810 }
00811 
00812 //#############################################################################
00813 
00820 template <class T> inline int
00821 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00822 {
00823     int numberRead;
00824     numberRead = fread(&newSize,sizeof(int),1,fp);
00825     if (numberRead!=1)
00826         return 1;
00827     int returnCode=0;
00828     if (size!=newSize&&(newSize||array))
00829         returnCode=2;
00830     if (newSize) {
00831         array = new T [newSize];
00832         numberRead = fread(array,sizeof(T),newSize,fp);
00833         if (numberRead!=newSize)
00834             returnCode=1;
00835     } else {
00836         array = NULL;
00837     }
00838     return returnCode;
00839 }
00840 
00841 //#############################################################################
00842 
00844 inline double CoinCbrt(double x)
00845 {
00846 #if defined(_MSC_VER) 
00847     return pow(x,(1./3.));
00848 #else
00849     return cbrt(x);
00850 #endif
00851 }
00854 #if defined COIN_OWN_RANDOM_32
00855 class CoinThreadRandom  {
00856 public:
00861   CoinThreadRandom()
00862   { seed_=12345678;}
00864   CoinThreadRandom(int seed)
00865   { 
00866     seed_ = seed;
00867   }
00869   ~CoinThreadRandom() {}
00870   // Copy
00871   CoinThreadRandom(const CoinThreadRandom & rhs)
00872   { seed_ = rhs.seed_;}
00873   // Assignment
00874   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00875   {
00876     if (this != &rhs) {
00877       seed_ = rhs.seed_;
00878     }
00879     return *this;
00880   }
00881 
00883   
00888   inline void setSeed(int seed)
00889   { 
00890     seed_ = seed;
00891   }
00893   inline double randomDouble() const
00894   {
00895     double retVal;
00896     seed_ = 1664525*(seed_)+1013904223;
00897     retVal = (((double) seed_)/4294967296.0);
00898     return retVal;
00899   }
00901   
00902   
00903 protected:
00907 
00908   mutable unsigned int seed_;
00910 };
00911 #else
00912 class CoinThreadRandom  {
00913 public:
00918   CoinThreadRandom()
00919   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00921   CoinThreadRandom(const unsigned short seed[3])
00922   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00924   CoinThreadRandom(int seed)
00925   { 
00926     union { int i[2]; unsigned short int s[4];} put;
00927     put.i[0]=seed;
00928     put.i[1]=seed;
00929     memcpy(seed_,put.s,3*sizeof(unsigned short));
00930   }
00932   ~CoinThreadRandom() {}
00933   // Copy
00934   CoinThreadRandom(const CoinThreadRandom & rhs)
00935   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00936   // Assignment
00937   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00938   {
00939     if (this != &rhs) {
00940       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00941     }
00942     return *this;
00943   }
00944 
00946   
00951   inline void setSeed(const unsigned short seed[3])
00952   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00954   inline void setSeed(int seed)
00955   { 
00956     union { int i[2]; unsigned short int s[4];} put;
00957     put.i[0]=seed;
00958     put.i[1]=seed;
00959     memcpy(seed_,put.s,3*sizeof(unsigned short));
00960   }
00962   inline double randomDouble() const
00963   {
00964     double retVal;
00965 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00966     retVal=rand();
00967     retVal=retVal/(double) RAND_MAX;
00968 #else
00969     retVal = erand48(seed_);
00970 #endif
00971     return retVal;
00972   }
00974   
00975   
00976 protected:
00980 
00981   mutable unsigned short seed_[3];
00983 };
00984 #endif
00985 #endif

Generated on Sun Nov 14 14:06:32 2010 for Coin-All by  doxygen 1.4.7