home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Libraries / VideoToolbox 94.11.17 / VideoToolboxSources / nrand.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-26  |  2.0 KB  |  58 lines  |  [TEXT/KAHL]

  1. /*
  2. nrand.c
  3. nrand(n) returns a random integer in the range [0, n-1], provided n>0. If n is zero
  4. the returned value is zero.
  5.  
  6. nrandU() and nrandUL() are obsolete; use nrand() instead.
  7.  
  8. HISTORY:
  9. 4/29/88    dgp    wrote it.
  10. 3/19/90    dgp    made it portable between THINK C and MPW C.
  11. 9/13/92    dgp    Using THINK C's Disassembler I noticed that I could substantially speed
  12.             up the code, replacing the long division by a bit shift. The answers for 
  13.             legal values of n, i.e. n>0, are unchanged, but the answers for values of 
  14.             n outside that range have changed because I now explicitly cast n
  15.             to unsigned long rather than long. (Bit shifting and division give different
  16.             answers when the numerator is negative.)
  17.             Added nrandU() and nrandUL().
  18. 9/18/92    dgp    Cast rand() from int to unsigned short to prompt THINK C to generate 
  19.             tighter code.
  20. 3/26/94    dgp Replaced all three routines (nrand, nrandU, and nrandUL) by one universal
  21.             routine, nrand, that uses integer arithmetic (as in nrandU) if n is small 
  22.             enough, and otherwise uses double arithmetic (as in nrandUL). However,
  23.             even for small n, the new routine differs from the old nrandU() because
  24.             I replaced the call to rand() by a call to randU() because this
  25.             allows us to use integer arithmetic for values of n up to
  26.             USHRT_MAX instead of just SHRT_MAX.        
  27. */
  28. #include "VideoToolbox.h"
  29. #include <assert.h>
  30.  
  31. unsigned long nrand(unsigned long n)
  32. {
  33.     if(ULONG_MAX/USHRT_MAX/USHRT_MAX>=1 && n<=USHRT_MAX)return n*randU()>>16;
  34.     else return (unsigned long)((double)n*randUL()/(ULONG_MAX+1.0));
  35. }
  36.  
  37. #if 0    // Old version, before March, 1994.
  38.     int nrand(short n)
  39.     {
  40.         assert(RAND_MAX+1UL==1UL<<15);
  41.         return (unsigned long)n*rand()>>15;
  42.     }
  43.         
  44.     #if RAND_MAX > ULONG_MAX/USHRT_MAX
  45.         #error "nrandU() assumes that an unsigned long can hold the product of unsigned short & rand()."
  46.     #endif
  47.     
  48.     unsigned short nrandU(unsigned short n)
  49.     {
  50.         assert(RAND_MAX+1UL==1UL<<15);
  51.         return (unsigned long)n*(unsigned short)rand()>>15;
  52.     }
  53.  
  54.     unsigned long nrandUL(unsigned long n)
  55.     {
  56.         return (unsigned long)((double)n*randUL()/(ULONG_MAX+1.0)); 
  57.     }
  58. #endif