random.bmx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. Strict
  2. Rem
  3. bbdoc: Math/Random numbers
  4. End Rem
  5. Module BRL.Random
  6. ModuleInfo "Version: 1.05"
  7. ModuleInfo "Author: Mark Sibly, Floyd"
  8. ModuleInfo "License: zlib/libpng"
  9. ModuleInfo "Copyright: Blitz Research Ltd"
  10. ModuleInfo "Modserver: BRL"
  11. ModuleInfo "History: 1.05 Release"
  12. ModuleInfo "History: Fixed Rand() with negative min value bug"
  13. Private
  14. Global rnd_state=$1234
  15. Const RND_A=48271,RND_M=2147483647,RND_Q=44488,RND_R=3399
  16. Public
  17. Rem
  18. bbdoc: Generate random float
  19. returns: A random float in the range 0 (inclusive) to 1 (exclusive)
  20. End Rem
  21. Function RndFloat#()
  22. rnd_state=RND_A*(rnd_state Mod RND_Q)-RND_R*(rnd_state/RND_Q)
  23. If rnd_state<0 rnd_state=rnd_state+RND_M
  24. Return (rnd_state & $ffffff0) / 268435456# 'divide by 2^28
  25. End Function
  26. Rem
  27. bbdoc: Generate random double
  28. returns: A random double in the range 0 (inclusive) to 1 (exclusive)
  29. End Rem
  30. Function RndDouble!()
  31. Const TWO27! = 134217728.0 '2 ^ 27
  32. Const TWO29! = 536870912.0 '2 ^ 29
  33. rnd_state=RND_A*(rnd_state Mod RND_Q)-RND_R*(rnd_state/RND_Q)
  34. If rnd_state<0 rnd_state=rnd_state+RND_M
  35. Local r_hi! = rnd_state & $1ffffffc
  36. rnd_state=RND_A*(rnd_state Mod RND_Q)-RND_R*(rnd_state/RND_Q)
  37. If rnd_state<0 rnd_state=rnd_state+RND_M
  38. Local r_lo! = rnd_state & $1ffffff8
  39. Return (r_hi + r_lo/TWO27)/TWO29
  40. End Function
  41. Rem
  42. bbdoc: Generate random double
  43. returns: A random double in the range min (inclusive) to max (exclusive)
  44. about:
  45. The optional parameters allow you to use Rnd in 3 ways:
  46. [ @Format | @Result
  47. * &Rnd() | Random double in the range 0 (inclusive) to 1 (exclusive)
  48. * &Rnd(_x_) | Random double in the range 0 (inclusive) to n (exclusive)
  49. * &Rnd(_x,y_) | Random double in the range x (inclusive) to y (exclusive)
  50. ]
  51. End Rem
  52. Function Rnd!( min_value!=1,max_value!=0 )
  53. If max_value>min_value Return RndDouble()*(max_value-min_value)+min_value
  54. Return RndDouble()*(min_value-max_value)+max_value
  55. End Function
  56. Rem
  57. bbdoc: Generate random integer
  58. returns: A random integer in the range min (inclusive) to max (inclusive)
  59. about:
  60. The optional parameter allows you to use #Rand in 2 ways:
  61. [ @Format | @Result
  62. * &Rand(x) | Random integer in the range 1 to x (inclusive)
  63. * &Rand(x,y) | Random integer in the range x to y (inclusive)
  64. ]
  65. End Rem
  66. Function Rand( min_value,max_value=1 )
  67. Local range=max_value-min_value
  68. If range>0 Return Int( RndDouble()*(1+range) )+min_value
  69. Return Int( RndDouble()*(1-range) )+max_value
  70. End Function
  71. Rem
  72. bbdoc: Set random number generator seed
  73. End Rem
  74. Function SeedRnd( seed )
  75. rnd_state=seed & $7fffffff 'enforces rnd_state >= 0
  76. If rnd_state=0 Or rnd_state=RND_M rnd_state=$1234 'disallow 0 and M
  77. End Function
  78. Rem
  79. bbdoc: Get random number generator seed
  80. returns: The current random number generator seed
  81. about: Use in conjunction with SeedRnd, RndSeed allows you to reproduce sequences of random
  82. numbers.
  83. End Rem
  84. Function RndSeed()
  85. Return rnd_state
  86. End Function