00001
00002
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
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
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
00102
00103
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 std::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||size) {
00174 T * arrayNew = new T[size];
00175 assert (copySize<=size);
00176 std::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 std::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 std::memcpy(arrayNew,array,size*sizeof(T));
00212 } else {
00213 std::memset(arrayNew,0,size*sizeof(T));
00214 }
00215 return arrayNew;
00216 }
00217
00218
00219
00220
00228 #ifndef COIN_USE_RESTRICT
00229 template <class T> inline void
00230 CoinMemcpyN(register const T* from, const int size, register T* to)
00231 {
00232 #ifndef _MSC_VER
00233 #ifdef USE_MEMCPY
00234
00235 #ifndef NDEBUG
00236
00237 if (size < 0)
00238 throw CoinError("trying to copy negative number of entries",
00239 "CoinMemcpyN", "");
00240
00241 #if 0
00242
00243
00244
00245 const long dist = to - from;
00246 if (-size < dist && dist < size)
00247 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00248 #endif
00249 #endif
00250 std::memcpy(to,from,size*sizeof(T));
00251 #else
00252 if (size == 0 || from == to)
00253 return;
00254
00255 if (size < 0)
00256 throw CoinError("trying to copy negative number of entries",
00257 "CoinMemcpyN", "");
00258
00259 #if 0
00260
00261
00262
00263 const long dist = to - from;
00264 if (-size < dist && dist < size)
00265 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00266 #endif
00267
00268 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00269 to[0] = from[0];
00270 to[1] = from[1];
00271 to[2] = from[2];
00272 to[3] = from[3];
00273 to[4] = from[4];
00274 to[5] = from[5];
00275 to[6] = from[6];
00276 to[7] = from[7];
00277 }
00278 switch (size % 8) {
00279 case 7: to[6] = from[6];
00280 case 6: to[5] = from[5];
00281 case 5: to[4] = from[4];
00282 case 4: to[3] = from[3];
00283 case 3: to[2] = from[2];
00284 case 2: to[1] = from[1];
00285 case 1: to[0] = from[0];
00286 case 0: break;
00287 }
00288 #endif
00289 #else
00290 CoinCopyN(from, size, to);
00291 #endif
00292 }
00293 #else
00294 template <class T> inline void
00295 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
00296 {
00297 T * put = (T *) to;
00298 const T * get = (const T *) from;
00299 for ( ; 0<size ; --size)
00300 *put++ = *get++;
00301 }
00302 #endif
00303
00304
00305
00310 template <class T> inline void
00311 CoinMemcpy(register const T* first, register const T* last,
00312 register T* to)
00313 {
00314 CoinMemcpyN(first, static_cast<int>(last - first), to);
00315 }
00316
00317
00318
00325 template <class T> inline void
00326 CoinFillN(register T* to, const int size, register const T value)
00327 {
00328 if (size == 0)
00329 return;
00330
00331 if (size < 0)
00332 throw CoinError("trying to fill negative number of entries",
00333 "CoinFillN", "");
00334
00335 #if 1
00336 for (register int n = size / 8; n > 0; --n, to += 8) {
00337 to[0] = value;
00338 to[1] = value;
00339 to[2] = value;
00340 to[3] = value;
00341 to[4] = value;
00342 to[5] = value;
00343 to[6] = value;
00344 to[7] = value;
00345 }
00346 switch (size % 8) {
00347 case 7: to[6] = value;
00348 case 6: to[5] = value;
00349 case 5: to[4] = value;
00350 case 4: to[3] = value;
00351 case 3: to[2] = value;
00352 case 2: to[1] = value;
00353 case 1: to[0] = value;
00354 case 0: break;
00355 }
00356 #else
00357
00358 register int n = (size + 7) / 8;
00359 --to;
00360 switch (size % 8) {
00361 case 0: do{ *++to = value;
00362 case 7: *++to = value;
00363 case 6: *++to = value;
00364 case 5: *++to = value;
00365 case 4: *++to = value;
00366 case 3: *++to = value;
00367 case 2: *++to = value;
00368 case 1: *++to = value;
00369 }while(--n>0);
00370 }
00371 #endif
00372 }
00373
00374
00375
00379 template <class T> inline void
00380 CoinFill(register T* first, register T* last, const T value)
00381 {
00382 CoinFillN(first, last - first, value);
00383 }
00384
00385
00386
00393 template <class T> inline void
00394 CoinZeroN(register T* to, const int size)
00395 {
00396 #ifdef USE_MEMCPY
00397
00398 #ifndef NDEBUG
00399
00400 if (size < 0)
00401 throw CoinError("trying to fill negative number of entries",
00402 "CoinZeroN", "");
00403 #endif
00404 memset(to,0,size*sizeof(T));
00405 #else
00406 if (size == 0)
00407 return;
00408
00409 if (size < 0)
00410 throw CoinError("trying to fill negative number of entries",
00411 "CoinZeroN", "");
00412 #if 1
00413 for (register int n = size / 8; n > 0; --n, to += 8) {
00414 to[0] = 0;
00415 to[1] = 0;
00416 to[2] = 0;
00417 to[3] = 0;
00418 to[4] = 0;
00419 to[5] = 0;
00420 to[6] = 0;
00421 to[7] = 0;
00422 }
00423 switch (size % 8) {
00424 case 7: to[6] = 0;
00425 case 6: to[5] = 0;
00426 case 5: to[4] = 0;
00427 case 4: to[3] = 0;
00428 case 3: to[2] = 0;
00429 case 2: to[1] = 0;
00430 case 1: to[0] = 0;
00431 case 0: break;
00432 }
00433 #else
00434
00435 register int n = (size + 7) / 8;
00436 --to;
00437 switch (size % 8) {
00438 case 0: do{ *++to = 0;
00439 case 7: *++to = 0;
00440 case 6: *++to = 0;
00441 case 5: *++to = 0;
00442 case 4: *++to = 0;
00443 case 3: *++to = 0;
00444 case 2: *++to = 0;
00445 case 1: *++to = 0;
00446 }while(--n>0);
00447 }
00448 #endif
00449 #endif
00450 }
00452 inline void
00453 CoinCheckDoubleZero(double * to, const int size)
00454 {
00455 int n=0;
00456 for (int j=0;j<size;j++) {
00457 if (to[j])
00458 n++;
00459 }
00460 if (n) {
00461 printf("array of length %d should be zero has %d nonzero\n",size,n);
00462 }
00463 }
00465 inline void
00466 CoinCheckIntZero(int * to, const int size)
00467 {
00468 int n=0;
00469 for (int j=0;j<size;j++) {
00470 if (to[j])
00471 n++;
00472 }
00473 if (n) {
00474 printf("array of length %d should be zero has %d nonzero\n",size,n);
00475 }
00476 }
00477
00478
00479
00483 template <class T> inline void
00484 CoinZero(register T* first, register T* last)
00485 {
00486 CoinZeroN(first, last - first);
00487 }
00488
00489
00490
00492 inline char * CoinStrdup(const char * name)
00493 {
00494 char* dup = NULL;
00495 if (name) {
00496 const int len = strlen(name);
00497 dup = (char*)malloc(len+1);
00498 CoinMemcpyN(name, len, dup);
00499 dup[len] = 0;
00500 }
00501 return dup;
00502 }
00503
00504
00505
00509 template <class T> inline T
00510 CoinMax(register const T x1, register const T x2)
00511 {
00512 return (x1 > x2) ? x1 : x2;
00513 }
00514
00515
00516
00520 template <class T> inline T
00521 CoinMin(register const T x1, register const T x2)
00522 {
00523 return (x1 < x2) ? x1 : x2;
00524 }
00525
00526
00527
00531 template <class T> inline T
00532 CoinAbs(const T value)
00533 {
00534 return value<0 ? -value : value;
00535 }
00536
00537
00538
00542 template <class T> inline bool
00543 CoinIsSorted(register const T* first, const int size)
00544 {
00545 if (size == 0)
00546 return true;
00547
00548 if (size < 0)
00549 throw CoinError("negative number of entries", "CoinIsSorted", "");
00550
00551 #if 1
00552
00553 const int size1 = size - 1;
00554 for (register int n = size1 / 8; n > 0; --n, first += 8) {
00555 if (first[8] < first[7]) return false;
00556 if (first[7] < first[6]) return false;
00557 if (first[6] < first[5]) return false;
00558 if (first[5] < first[4]) return false;
00559 if (first[4] < first[3]) return false;
00560 if (first[3] < first[2]) return false;
00561 if (first[2] < first[1]) return false;
00562 if (first[1] < first[0]) return false;
00563 }
00564
00565 switch (size1 % 8) {
00566 case 7: if (first[7] < first[6]) return false;
00567 case 6: if (first[6] < first[5]) return false;
00568 case 5: if (first[5] < first[4]) return false;
00569 case 4: if (first[4] < first[3]) return false;
00570 case 3: if (first[3] < first[2]) return false;
00571 case 2: if (first[2] < first[1]) return false;
00572 case 1: if (first[1] < first[0]) return false;
00573 case 0: break;
00574 }
00575 #else
00576 register const T* next = first;
00577 register const T* last = first + size;
00578 for (++next; next != last; first = next, ++next)
00579 if (*next < *first)
00580 return false;
00581 #endif
00582 return true;
00583 }
00584
00585
00586
00590 template <class T> inline bool
00591 CoinIsSorted(register const T* first, register const T* last)
00592 {
00593 return CoinIsSorted(first, static_cast<int>(last - first));
00594 }
00595
00596
00597
00601 template <class T> inline void
00602 CoinIotaN(register T* first, const int size, register T init)
00603 {
00604 if (size == 0)
00605 return;
00606
00607 if (size < 0)
00608 throw CoinError("negative number of entries", "CoinIotaN", "");
00609
00610 #if 1
00611 for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00612 first[0] = init;
00613 first[1] = init + 1;
00614 first[2] = init + 2;
00615 first[3] = init + 3;
00616 first[4] = init + 4;
00617 first[5] = init + 5;
00618 first[6] = init + 6;
00619 first[7] = init + 7;
00620 }
00621 switch (size % 8) {
00622 case 7: first[6] = init + 6;
00623 case 6: first[5] = init + 5;
00624 case 5: first[4] = init + 4;
00625 case 4: first[3] = init + 3;
00626 case 3: first[2] = init + 2;
00627 case 2: first[1] = init + 1;
00628 case 1: first[0] = init;
00629 case 0: break;
00630 }
00631 #else
00632
00633 register int n = (size + 7) / 8;
00634 --first;
00635 --init;
00636 switch (size % 8) {
00637 case 0: do{ *++first = ++init;
00638 case 7: *++first = ++init;
00639 case 6: *++first = ++init;
00640 case 5: *++first = ++init;
00641 case 4: *++first = ++init;
00642 case 3: *++first = ++init;
00643 case 2: *++first = ++init;
00644 case 1: *++first = ++init;
00645 }while(--n>0);
00646 }
00647 #endif
00648 }
00649
00650
00651
00655 template <class T> inline void
00656 CoinIota(T* first, const T* last, T init)
00657 {
00658 CoinIotaN(first, last-first, init);
00659 }
00660
00661
00662
00668 template <class T> inline T *
00669 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00670 const int * firstDelPos, const int * lastDelPos)
00671 {
00672 int delNum = lastDelPos - firstDelPos;
00673 if (delNum == 0)
00674 return arrayLast;
00675
00676 if (delNum < 0)
00677 throw CoinError("trying to delete negative number of entries",
00678 "CoinDeleteEntriesFromArray", "");
00679
00680 int * delSortedPos = NULL;
00681 if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00682 std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00683
00684 delSortedPos = new int[delNum];
00685 CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00686 std::sort(delSortedPos, delSortedPos + delNum);
00687 delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00688 }
00689 const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00690
00691 const int last = delNum - 1;
00692 int size = delSorted[0];
00693 for (int i = 0; i < last; ++i) {
00694 const int copyFirst = delSorted[i] + 1;
00695 const int copyLast = delSorted[i+1];
00696 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00697 arrayFirst + size);
00698 size += copyLast - copyFirst;
00699 }
00700 const int copyFirst = delSorted[last] + 1;
00701 const int copyLast = arrayLast - arrayFirst;
00702 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00703 arrayFirst + size);
00704 size += copyLast - copyFirst;
00705
00706 if (delSortedPos)
00707 delete[] delSortedPos;
00708
00709 return arrayFirst + size;
00710 }
00711
00712
00713
00714 #define COIN_OWN_RANDOM_32
00715
00716 #if defined COIN_OWN_RANDOM_32
00717
00718
00719
00720
00721
00722
00723
00725 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00726 {
00727 static unsigned int last = 123456;
00728 if (isSeed) {
00729 last = seed;
00730 } else {
00731 last = 1664525*last+1013904223;
00732 return (((double) last)/4294967296.0);
00733 }
00734 return(0.0);
00735 }
00737 inline void CoinSeedRandom(int iseed)
00738 {
00739 CoinDrand48(true, iseed);
00740 }
00741
00742 #else // COIN_OWN_RANDOM_32
00743
00744 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00745
00746 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00747 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00748
00749 #else
00750
00751 inline double CoinDrand48() { return drand48(); }
00752 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00753
00754 #endif
00755
00756 #endif // COIN_OWN_RANDOM_32
00757
00758
00759
00762 inline char CoinFindDirSeparator()
00763 {
00764 int size = 1000;
00765 char* buf = 0;
00766 while (true) {
00767 buf = new char[size];
00768 if (getcwd(buf, size))
00769 break;
00770 delete[] buf;
00771 buf = 0;
00772 size = 2*size;
00773 }
00774
00775
00776 char dirsep = buf[0] == '/' ? '/' : '\\';
00777 delete[] buf;
00778 return dirsep;
00779 }
00780
00781
00782 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00783 const size_t len)
00784 {
00785 for (size_t i = 0; i < len; ++i) {
00786 if (s0[i] == 0) {
00787 return s1[i] == 0 ? 0 : -1;
00788 }
00789 if (s1[i] == 0) {
00790 return 1;
00791 }
00792 const int c0 = tolower(s0[i]);
00793 const int c1 = tolower(s1[i]);
00794 if (c0 < c1)
00795 return -1;
00796 if (c0 > c1)
00797 return 1;
00798 }
00799 return 0;
00800 }
00801
00802
00803
00805 template <class T> inline void CoinSwap (T &x, T &y)
00806 {
00807 T t = x;
00808 x = y;
00809 y = t;
00810 }
00811
00812
00813
00818 template <class T> inline int
00819 CoinToFile( const T* array, int size, FILE * fp)
00820 {
00821 int numberWritten;
00822 if (array&&size) {
00823 numberWritten = fwrite(&size,sizeof(int),1,fp);
00824 if (numberWritten!=1)
00825 return 1;
00826 numberWritten = fwrite(array,sizeof(T),size,fp);
00827 if (numberWritten!=size)
00828 return 1;
00829 } else {
00830 size = 0;
00831 numberWritten = fwrite(&size,sizeof(int),1,fp);
00832 if (numberWritten!=1)
00833 return 1;
00834 }
00835 return 0;
00836 }
00837
00838
00839
00846 template <class T> inline int
00847 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00848 {
00849 int numberRead;
00850 numberRead = fread(&newSize,sizeof(int),1,fp);
00851 if (numberRead!=1)
00852 return 1;
00853 int returnCode=0;
00854 if (size!=newSize&&(newSize||array))
00855 returnCode=2;
00856 if (newSize) {
00857 array = new T [newSize];
00858 numberRead = fread(array,sizeof(T),newSize,fp);
00859 if (numberRead!=newSize)
00860 returnCode=1;
00861 } else {
00862 array = NULL;
00863 }
00864 return returnCode;
00865 }
00866
00867
00868
00870 inline double CoinCbrt(double x)
00871 {
00872 #if defined(_MSC_VER)
00873 return pow(x,(1./3.));
00874 #else
00875 return cbrt(x);
00876 #endif
00877 }
00880 #if defined COIN_OWN_RANDOM_32
00881 class CoinThreadRandom {
00882 public:
00887 CoinThreadRandom()
00888 { seed_=12345678;}
00890 CoinThreadRandom(int seed)
00891 {
00892 seed_ = seed;
00893 }
00895 ~CoinThreadRandom() {}
00896
00897 CoinThreadRandom(const CoinThreadRandom & rhs)
00898 { seed_ = rhs.seed_;}
00899
00900 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00901 {
00902 if (this != &rhs) {
00903 seed_ = rhs.seed_;
00904 }
00905 return *this;
00906 }
00907
00909
00914 inline void setSeed(int seed)
00915 {
00916 seed_ = seed;
00917 }
00919 inline double randomDouble() const
00920 {
00921 double retVal;
00922 seed_ = 1664525*(seed_)+1013904223;
00923 retVal = (((double) seed_)/4294967296.0);
00924 return retVal;
00925 }
00927
00928
00929 protected:
00933
00934 mutable unsigned int seed_;
00936 };
00937 #else
00938 class CoinThreadRandom {
00939 public:
00944 CoinThreadRandom()
00945 { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00947 CoinThreadRandom(const unsigned short seed[3])
00948 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00950 CoinThreadRandom(int seed)
00951 {
00952 union { int i[2]; unsigned short int s[4];} put;
00953 put.i[0]=seed;
00954 put.i[1]=seed;
00955 memcpy(seed_,put.s,3*sizeof(unsigned short));
00956 }
00958 ~CoinThreadRandom() {}
00959
00960 CoinThreadRandom(const CoinThreadRandom & rhs)
00961 { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00962
00963 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00964 {
00965 if (this != &rhs) {
00966 memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00967 }
00968 return *this;
00969 }
00970
00972
00977 inline void setSeed(const unsigned short seed[3])
00978 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00980 inline void setSeed(int seed)
00981 {
00982 union { int i[2]; unsigned short int s[4];} put;
00983 put.i[0]=seed;
00984 put.i[1]=seed;
00985 memcpy(seed_,put.s,3*sizeof(unsigned short));
00986 }
00988 inline double randomDouble() const
00989 {
00990 double retVal;
00991 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00992 retVal=rand();
00993 retVal=retVal/(double) RAND_MAX;
00994 #else
00995 retVal = erand48(seed_);
00996 #endif
00997 return retVal;
00998 }
01000
01001
01002 protected:
01006
01007 mutable unsigned short seed_[3];
01009 };
01010 #endif
01011 #endif