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
00014 #include <cstdlib>
00015 #include <cstdio>
00016 #include "CoinError.hpp"
00017 #include "CoinFinite.hpp"
00018
00019
00025 template <class T> inline void
00026 CoinCopyN(register const T* from, const int size, register T* to)
00027 {
00028 if (size == 0 || from == to)
00029 return;
00030
00031 if (size < 0)
00032 throw CoinError("trying to copy negative number of entries",
00033 "CoinCopyN", "");
00034
00035 register int n = (size + 7) / 8;
00036 if (to > from) {
00037 register const T* downfrom = from + size;
00038 register T* downto = to + size;
00039
00040 switch (size % 8) {
00041 case 0: do{ *--downto = *--downfrom;
00042 case 7: *--downto = *--downfrom;
00043 case 6: *--downto = *--downfrom;
00044 case 5: *--downto = *--downfrom;
00045 case 4: *--downto = *--downfrom;
00046 case 3: *--downto = *--downfrom;
00047 case 2: *--downto = *--downfrom;
00048 case 1: *--downto = *--downfrom;
00049 }while(--n>0);
00050 }
00051 } else {
00052
00053 --from;
00054 --to;
00055 switch (size % 8) {
00056 case 0: do{ *++to = *++from;
00057 case 7: *++to = *++from;
00058 case 6: *++to = *++from;
00059 case 5: *++to = *++from;
00060 case 4: *++to = *++from;
00061 case 3: *++to = *++from;
00062 case 2: *++to = *++from;
00063 case 1: *++to = *++from;
00064 }while(--n>0);
00065 }
00066 }
00067 }
00068
00069
00070
00075 template <class T> inline void
00076 CoinCopy(register const T* first, register const T* last, register T* to)
00077 {
00078 CoinCopyN(first, last - first, to);
00079 }
00080
00081
00082
00090 template <class T> inline void
00091 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00092 {
00093 #ifndef _MSC_VER
00094 if (size == 0 || from == to)
00095 return;
00096
00097 if (size < 0)
00098 throw CoinError("trying to copy negative number of entries",
00099 "CoinDisjointCopyN", "");
00100
00101 #if 0
00102
00103
00104
00105 const long dist = to - from;
00106 if (-size < dist && dist < size)
00107 throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00108 #endif
00109
00110 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00111 to[0] = from[0];
00112 to[1] = from[1];
00113 to[2] = from[2];
00114 to[3] = from[3];
00115 to[4] = from[4];
00116 to[5] = from[5];
00117 to[6] = from[6];
00118 to[7] = from[7];
00119 }
00120 switch (size % 8) {
00121 case 7: to[6] = from[6];
00122 case 6: to[5] = from[5];
00123 case 5: to[4] = from[4];
00124 case 4: to[3] = from[3];
00125 case 3: to[2] = from[2];
00126 case 2: to[1] = from[1];
00127 case 1: to[0] = from[0];
00128 case 0: break;
00129 }
00130 #else
00131 CoinCopyN(from, size, to);
00132 #endif
00133 }
00134
00135
00136
00141 template <class T> inline void
00142 CoinDisjointCopy(register const T* first, register const T* last,
00143 register T* to)
00144 {
00145 CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00146 }
00147
00148
00149
00154 template <class T> inline T*
00155 CoinCopyOfArray( const T * array, const int size)
00156 {
00157 if (array) {
00158 T * arrayNew = new T[size];
00159 std::memcpy(arrayNew,array,size*sizeof(T));
00160 return arrayNew;
00161 } else {
00162 return NULL;
00163 }
00164 }
00165
00166
00171 template <class T> inline T*
00172 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00173 {
00174 if (array||size) {
00175 T * arrayNew = new T[size];
00176 assert (copySize<=size);
00177 std::memcpy(arrayNew,array,copySize*sizeof(T));
00178 return arrayNew;
00179 } else {
00180 return NULL;
00181 }
00182 }
00183
00188 template <class T> inline T*
00189 CoinCopyOfArray( const T * array, const int size, T value)
00190 {
00191 T * arrayNew = new T[size];
00192 if (array) {
00193 std::memcpy(arrayNew,array,size*sizeof(T));
00194 } else {
00195 int i;
00196 for (i=0;i<size;i++)
00197 arrayNew[i] = value;
00198 }
00199 return arrayNew;
00200 }
00201
00202
00207 template <class T> inline T*
00208 CoinCopyOfArrayOrZero( const T * array , const int size)
00209 {
00210 T * arrayNew = new T[size];
00211 if (array) {
00212 std::memcpy(arrayNew,array,size*sizeof(T));
00213 } else {
00214 std::memset(arrayNew,0,size*sizeof(T));
00215 }
00216 return arrayNew;
00217 }
00218
00219
00220
00221
00229 #ifndef COIN_USE_RESTRICT
00230 template <class T> inline void
00231 CoinMemcpyN(register const T* from, const int size, register T* to)
00232 {
00233 #ifndef _MSC_VER
00234 #ifdef USE_MEMCPY
00235
00236 #ifndef NDEBUG
00237
00238 if (size < 0)
00239 throw CoinError("trying to copy negative number of entries",
00240 "CoinMemcpyN", "");
00241
00242 #if 0
00243
00244
00245
00246 const long dist = to - from;
00247 if (-size < dist && dist < size)
00248 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00249 #endif
00250 #endif
00251 std::memcpy(to,from,size*sizeof(T));
00252 #else
00253 if (size == 0 || from == to)
00254 return;
00255
00256 if (size < 0)
00257 throw CoinError("trying to copy negative number of entries",
00258 "CoinMemcpyN", "");
00259
00260 #if 0
00261
00262
00263
00264 const long dist = to - from;
00265 if (-size < dist && dist < size)
00266 throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00267 #endif
00268
00269 for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00270 to[0] = from[0];
00271 to[1] = from[1];
00272 to[2] = from[2];
00273 to[3] = from[3];
00274 to[4] = from[4];
00275 to[5] = from[5];
00276 to[6] = from[6];
00277 to[7] = from[7];
00278 }
00279 switch (size % 8) {
00280 case 7: to[6] = from[6];
00281 case 6: to[5] = from[5];
00282 case 5: to[4] = from[4];
00283 case 4: to[3] = from[3];
00284 case 3: to[2] = from[2];
00285 case 2: to[1] = from[1];
00286 case 1: to[0] = from[0];
00287 case 0: break;
00288 }
00289 #endif
00290 #else
00291 CoinCopyN(from, size, to);
00292 #endif
00293 }
00294 #else
00295 template <class T> inline void
00296 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
00297 {
00298 #ifdef USE_MEMCPY
00299 std::memcpy(to,from,size*sizeof(T));
00300 #else
00301 T * COIN_RESTRICT put = to;
00302 const T * COIN_RESTRICT get = from;
00303 for ( ; 0<size ; --size)
00304 *put++ = *get++;
00305 #endif
00306 }
00307 #endif
00308
00309
00310
00315 template <class T> inline void
00316 CoinMemcpy(register const T* first, register const T* last,
00317 register T* to)
00318 {
00319 CoinMemcpyN(first, static_cast<int>(last - first), to);
00320 }
00321
00322
00323
00330 template <class T> inline void
00331 CoinFillN(register T* to, const int size, register const T value)
00332 {
00333 if (size == 0)
00334 return;
00335
00336 if (size < 0)
00337 throw CoinError("trying to fill negative number of entries",
00338 "CoinFillN", "");
00339
00340 #if 1
00341 for (register int n = size / 8; n > 0; --n, to += 8) {
00342 to[0] = value;
00343 to[1] = value;
00344 to[2] = value;
00345 to[3] = value;
00346 to[4] = value;
00347 to[5] = value;
00348 to[6] = value;
00349 to[7] = value;
00350 }
00351 switch (size % 8) {
00352 case 7: to[6] = value;
00353 case 6: to[5] = value;
00354 case 5: to[4] = value;
00355 case 4: to[3] = value;
00356 case 3: to[2] = value;
00357 case 2: to[1] = value;
00358 case 1: to[0] = value;
00359 case 0: break;
00360 }
00361 #else
00362
00363 register int n = (size + 7) / 8;
00364 --to;
00365 switch (size % 8) {
00366 case 0: do{ *++to = value;
00367 case 7: *++to = value;
00368 case 6: *++to = value;
00369 case 5: *++to = value;
00370 case 4: *++to = value;
00371 case 3: *++to = value;
00372 case 2: *++to = value;
00373 case 1: *++to = value;
00374 }while(--n>0);
00375 }
00376 #endif
00377 }
00378
00379
00380
00384 template <class T> inline void
00385 CoinFill(register T* first, register T* last, const T value)
00386 {
00387 CoinFillN(first, last - first, value);
00388 }
00389
00390
00391
00398 template <class T> inline void
00399 CoinZeroN(register T* to, const int size)
00400 {
00401 #ifdef USE_MEMCPY
00402
00403 #ifndef NDEBUG
00404
00405 if (size < 0)
00406 throw CoinError("trying to fill negative number of entries",
00407 "CoinZeroN", "");
00408 #endif
00409 memset(to,0,size*sizeof(T));
00410 #else
00411 if (size == 0)
00412 return;
00413
00414 if (size < 0)
00415 throw CoinError("trying to fill negative number of entries",
00416 "CoinZeroN", "");
00417 #if 1
00418 for (register int n = size / 8; n > 0; --n, to += 8) {
00419 to[0] = 0;
00420 to[1] = 0;
00421 to[2] = 0;
00422 to[3] = 0;
00423 to[4] = 0;
00424 to[5] = 0;
00425 to[6] = 0;
00426 to[7] = 0;
00427 }
00428 switch (size % 8) {
00429 case 7: to[6] = 0;
00430 case 6: to[5] = 0;
00431 case 5: to[4] = 0;
00432 case 4: to[3] = 0;
00433 case 3: to[2] = 0;
00434 case 2: to[1] = 0;
00435 case 1: to[0] = 0;
00436 case 0: break;
00437 }
00438 #else
00439
00440 register int n = (size + 7) / 8;
00441 --to;
00442 switch (size % 8) {
00443 case 0: do{ *++to = 0;
00444 case 7: *++to = 0;
00445 case 6: *++to = 0;
00446 case 5: *++to = 0;
00447 case 4: *++to = 0;
00448 case 3: *++to = 0;
00449 case 2: *++to = 0;
00450 case 1: *++to = 0;
00451 }while(--n>0);
00452 }
00453 #endif
00454 #endif
00455 }
00457 inline void
00458 CoinCheckDoubleZero(double * to, const int size)
00459 {
00460 int n=0;
00461 for (int j=0;j<size;j++) {
00462 if (to[j])
00463 n++;
00464 }
00465 if (n) {
00466 printf("array of length %d should be zero has %d nonzero\n",size,n);
00467 }
00468 }
00470 inline void
00471 CoinCheckIntZero(int * to, const int size)
00472 {
00473 int n=0;
00474 for (int j=0;j<size;j++) {
00475 if (to[j])
00476 n++;
00477 }
00478 if (n) {
00479 printf("array of length %d should be zero has %d nonzero\n",size,n);
00480 }
00481 }
00482
00483
00484
00488 template <class T> inline void
00489 CoinZero(register T* first, register T* last)
00490 {
00491 CoinZeroN(first, last - first);
00492 }
00493
00494
00495
00497 inline char * CoinStrdup(const char * name)
00498 {
00499 char* dup = NULL;
00500 if (name) {
00501 const int len = static_cast<int>(strlen(name));
00502 dup = static_cast<char*>(malloc(len+1));
00503 CoinMemcpyN(name, len, dup);
00504 dup[len] = 0;
00505 }
00506 return dup;
00507 }
00508
00509
00510
00514 template <class T> inline T
00515 CoinMax(register const T x1, register const T x2)
00516 {
00517 return (x1 > x2) ? x1 : x2;
00518 }
00519
00520
00521
00525 template <class T> inline T
00526 CoinMin(register const T x1, register const T x2)
00527 {
00528 return (x1 < x2) ? x1 : x2;
00529 }
00530
00531
00532
00536 template <class T> inline T
00537 CoinAbs(const T value)
00538 {
00539 return value<0 ? -value : value;
00540 }
00541
00542
00543
00547 template <class T> inline bool
00548 CoinIsSorted(register const T* first, const int size)
00549 {
00550 if (size == 0)
00551 return true;
00552
00553 if (size < 0)
00554 throw CoinError("negative number of entries", "CoinIsSorted", "");
00555
00556 #if 1
00557
00558 const int size1 = size - 1;
00559 for (register int n = size1 / 8; n > 0; --n, first += 8) {
00560 if (first[8] < first[7]) return false;
00561 if (first[7] < first[6]) return false;
00562 if (first[6] < first[5]) return false;
00563 if (first[5] < first[4]) return false;
00564 if (first[4] < first[3]) return false;
00565 if (first[3] < first[2]) return false;
00566 if (first[2] < first[1]) return false;
00567 if (first[1] < first[0]) return false;
00568 }
00569
00570 switch (size1 % 8) {
00571 case 7: if (first[7] < first[6]) return false;
00572 case 6: if (first[6] < first[5]) return false;
00573 case 5: if (first[5] < first[4]) return false;
00574 case 4: if (first[4] < first[3]) return false;
00575 case 3: if (first[3] < first[2]) return false;
00576 case 2: if (first[2] < first[1]) return false;
00577 case 1: if (first[1] < first[0]) return false;
00578 case 0: break;
00579 }
00580 #else
00581 register const T* next = first;
00582 register const T* last = first + size;
00583 for (++next; next != last; first = next, ++next)
00584 if (*next < *first)
00585 return false;
00586 #endif
00587 return true;
00588 }
00589
00590
00591
00595 template <class T> inline bool
00596 CoinIsSorted(register const T* first, register const T* last)
00597 {
00598 return CoinIsSorted(first, static_cast<int>(last - first));
00599 }
00600
00601
00602
00606 template <class T> inline void
00607 CoinIotaN(register T* first, const int size, register T init)
00608 {
00609 if (size == 0)
00610 return;
00611
00612 if (size < 0)
00613 throw CoinError("negative number of entries", "CoinIotaN", "");
00614
00615 #if 1
00616 for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00617 first[0] = init;
00618 first[1] = init + 1;
00619 first[2] = init + 2;
00620 first[3] = init + 3;
00621 first[4] = init + 4;
00622 first[5] = init + 5;
00623 first[6] = init + 6;
00624 first[7] = init + 7;
00625 }
00626 switch (size % 8) {
00627 case 7: first[6] = init + 6;
00628 case 6: first[5] = init + 5;
00629 case 5: first[4] = init + 4;
00630 case 4: first[3] = init + 3;
00631 case 3: first[2] = init + 2;
00632 case 2: first[1] = init + 1;
00633 case 1: first[0] = init;
00634 case 0: break;
00635 }
00636 #else
00637
00638 register int n = (size + 7) / 8;
00639 --first;
00640 --init;
00641 switch (size % 8) {
00642 case 0: do{ *++first = ++init;
00643 case 7: *++first = ++init;
00644 case 6: *++first = ++init;
00645 case 5: *++first = ++init;
00646 case 4: *++first = ++init;
00647 case 3: *++first = ++init;
00648 case 2: *++first = ++init;
00649 case 1: *++first = ++init;
00650 }while(--n>0);
00651 }
00652 #endif
00653 }
00654
00655
00656
00660 template <class T> inline void
00661 CoinIota(T* first, const T* last, T init)
00662 {
00663 CoinIotaN(first, last-first, init);
00664 }
00665
00666
00667
00673 template <class T> inline T *
00674 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00675 const int * firstDelPos, const int * lastDelPos)
00676 {
00677 int delNum = lastDelPos - firstDelPos;
00678 if (delNum == 0)
00679 return arrayLast;
00680
00681 if (delNum < 0)
00682 throw CoinError("trying to delete negative number of entries",
00683 "CoinDeleteEntriesFromArray", "");
00684
00685 int * delSortedPos = NULL;
00686 if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00687 std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00688
00689 delSortedPos = new int[delNum];
00690 CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00691 std::sort(delSortedPos, delSortedPos + delNum);
00692 delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00693 }
00694 const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00695
00696 const int last = delNum - 1;
00697 int size = delSorted[0];
00698 for (int i = 0; i < last; ++i) {
00699 const int copyFirst = delSorted[i] + 1;
00700 const int copyLast = delSorted[i+1];
00701 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00702 arrayFirst + size);
00703 size += copyLast - copyFirst;
00704 }
00705 const int copyFirst = delSorted[last] + 1;
00706 const int copyLast = arrayLast - arrayFirst;
00707 CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00708 arrayFirst + size);
00709 size += copyLast - copyFirst;
00710
00711 if (delSortedPos)
00712 delete[] delSortedPos;
00713
00714 return arrayFirst + size;
00715 }
00716
00717
00718
00719 #define COIN_OWN_RANDOM_32
00720
00721 #if defined COIN_OWN_RANDOM_32
00722
00723
00724
00725
00726
00727
00728
00730 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00731 {
00732 static unsigned int last = 123456;
00733 if (isSeed) {
00734 last = seed;
00735 } else {
00736 last = 1664525*last+1013904223;
00737 return ((static_cast<double> (last))/4294967296.0);
00738 }
00739 return(0.0);
00740 }
00742 inline void CoinSeedRandom(int iseed)
00743 {
00744 CoinDrand48(true, iseed);
00745 }
00746
00747 #else // COIN_OWN_RANDOM_32
00748
00749 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00750
00751 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00752 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00753
00754 #else
00755
00756 inline double CoinDrand48() { return drand48(); }
00757 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00758
00759 #endif
00760
00761 #endif // COIN_OWN_RANDOM_32
00762
00763
00764
00767 inline char CoinFindDirSeparator()
00768 {
00769 int size = 1000;
00770 char* buf = 0;
00771 while (true) {
00772 buf = new char[size];
00773 if (getcwd(buf, size))
00774 break;
00775 delete[] buf;
00776 buf = 0;
00777 size = 2*size;
00778 }
00779
00780
00781 char dirsep = buf[0] == '/' ? '/' : '\\';
00782 delete[] buf;
00783 return dirsep;
00784 }
00785
00786
00787 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00788 const size_t len)
00789 {
00790 for (size_t i = 0; i < len; ++i) {
00791 if (s0[i] == 0) {
00792 return s1[i] == 0 ? 0 : -1;
00793 }
00794 if (s1[i] == 0) {
00795 return 1;
00796 }
00797 const int c0 = tolower(s0[i]);
00798 const int c1 = tolower(s1[i]);
00799 if (c0 < c1)
00800 return -1;
00801 if (c0 > c1)
00802 return 1;
00803 }
00804 return 0;
00805 }
00806
00807
00808
00810 template <class T> inline void CoinSwap (T &x, T &y)
00811 {
00812 T t = x;
00813 x = y;
00814 y = t;
00815 }
00816
00817
00818
00823 template <class T> inline int
00824 CoinToFile( const T* array, int size, FILE * fp)
00825 {
00826 int numberWritten;
00827 if (array&&size) {
00828 numberWritten = fwrite(&size,sizeof(int),1,fp);
00829 if (numberWritten!=1)
00830 return 1;
00831 numberWritten = fwrite(array,sizeof(T),size,fp);
00832 if (numberWritten!=size)
00833 return 1;
00834 } else {
00835 size = 0;
00836 numberWritten = fwrite(&size,sizeof(int),1,fp);
00837 if (numberWritten!=1)
00838 return 1;
00839 }
00840 return 0;
00841 }
00842
00843
00844
00851 template <class T> inline int
00852 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00853 {
00854 int numberRead;
00855 numberRead = fread(&newSize,sizeof(int),1,fp);
00856 if (numberRead!=1)
00857 return 1;
00858 int returnCode=0;
00859 if (size!=newSize&&(newSize||array))
00860 returnCode=2;
00861 if (newSize) {
00862 array = new T [newSize];
00863 numberRead = fread(array,sizeof(T),newSize,fp);
00864 if (numberRead!=newSize)
00865 returnCode=1;
00866 } else {
00867 array = NULL;
00868 }
00869 return returnCode;
00870 }
00871
00872
00873
00875 inline double CoinCbrt(double x)
00876 {
00877 #if defined(_MSC_VER)
00878 return pow(x,(1./3.));
00879 #else
00880 return cbrt(x);
00881 #endif
00882 }
00885 #if defined COIN_OWN_RANDOM_32
00886 class CoinThreadRandom {
00887 public:
00892 CoinThreadRandom()
00893 { seed_=12345678;}
00895 CoinThreadRandom(int seed)
00896 {
00897 seed_ = seed;
00898 }
00900 ~CoinThreadRandom() {}
00901
00902 CoinThreadRandom(const CoinThreadRandom & rhs)
00903 { seed_ = rhs.seed_;}
00904
00905 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00906 {
00907 if (this != &rhs) {
00908 seed_ = rhs.seed_;
00909 }
00910 return *this;
00911 }
00912
00914
00919 inline void setSeed(int seed)
00920 {
00921 seed_ = seed;
00922 }
00924 inline double randomDouble() const
00925 {
00926 double retVal;
00927 seed_ = 1664525*(seed_)+1013904223;
00928 retVal = ((static_cast<double> (seed_))/4294967296.0);
00929 return retVal;
00930 }
00932
00933
00934 protected:
00938
00939 mutable unsigned int seed_;
00941 };
00942 #else
00943 class CoinThreadRandom {
00944 public:
00949 CoinThreadRandom()
00950 { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00952 CoinThreadRandom(const unsigned short seed[3])
00953 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00955 CoinThreadRandom(int seed)
00956 {
00957 union { int i[2]; unsigned short int s[4];} put;
00958 put.i[0]=seed;
00959 put.i[1]=seed;
00960 memcpy(seed_,put.s,3*sizeof(unsigned short));
00961 }
00963 ~CoinThreadRandom() {}
00964
00965 CoinThreadRandom(const CoinThreadRandom & rhs)
00966 { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00967
00968 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00969 {
00970 if (this != &rhs) {
00971 memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00972 }
00973 return *this;
00974 }
00975
00977
00982 inline void setSeed(const unsigned short seed[3])
00983 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00985 inline void setSeed(int seed)
00986 {
00987 union { int i[2]; unsigned short int s[4];} put;
00988 put.i[0]=seed;
00989 put.i[1]=seed;
00990 memcpy(seed_,put.s,3*sizeof(unsigned short));
00991 }
00993 inline double randomDouble() const
00994 {
00995 double retVal;
00996 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00997 retVal=rand();
00998 retVal=retVal/(double) RAND_MAX;
00999 #else
01000 retVal = erand48(seed_);
01001 #endif
01002 return retVal;
01003 }
01005
01006
01007 protected:
01011
01012 mutable unsigned short seed_[3];
01014 };
01015 #endif
01016 #endif