changeset 15036:87f4e12f23ba draft

(svn r19652) -Fix: RandomRange() is used for bigger ranges in many cases, so generally extent it to handle 32 bits.
author frosch <frosch@openttd.org>
date Sat, 17 Apr 2010 11:49:25 +0000
parents cd12f24222ac
children ae5f1c6f349c
files bin/ai/regression/regression.nut bin/ai/regression/regression.txt src/core/random_func.cpp src/core/random_func.hpp src/industry_cmd.cpp
diffstat 5 files changed, 16 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/bin/ai/regression/regression.nut
+++ b/bin/ai/regression/regression.nut
@@ -192,9 +192,9 @@
 	print("  RandRange(2): " + AIBase.RandRange(2));
 	print("  RandRange(2): " + AIBase.RandRange(2));
 	print("  RandRange(2): " + AIBase.RandRange(2));
-	print("  RandRange(9): " + AIBase.RandRange(9));
-	print("  RandRange(9): " + AIBase.RandRange(9));
-	print("  RandRange(9): " + AIBase.RandRange(9));
+	print("  RandRange(1000000): " + AIBase.RandRange(1000000)); // 32 bit tests
+	print("  RandRange(1000000): " + AIBase.RandRange(1000000));
+	print("  RandRange(1000000): " + AIBase.RandRange(1000000));
 	print("  Chance(1, 2): " + AIBase.Chance(1, 2));
 	print("  Chance(1, 2): " + AIBase.Chance(1, 2));
 	print("  Chance(1, 2): " + AIBase.Chance(1, 2));
--- a/bin/ai/regression/regression.txt
+++ b/bin/ai/regression/regression.txt
@@ -96,10 +96,10 @@
   RandRange(1): 0
   RandRange(2): 0
   RandRange(2): 0
-  RandRange(2): 1
-  RandRange(9): 6
-  RandRange(9): 7
-  RandRange(9): 4
+  RandRange(2): 0
+  RandRange(1000000): 987346
+  RandRange(1000000): 781750
+  RandRange(1000000): 191841
   Chance(1, 2): true
   Chance(1, 2): false
   Chance(1, 2): false
--- a/src/core/random_func.cpp
+++ b/src/core/random_func.cpp
@@ -24,9 +24,9 @@
 	return this->state[1] = ROR(s, 3) - 1;
 }
 
-uint32 Randomizer::Next(uint16 max)
+uint32 Randomizer::Next(uint32 max)
 {
-	return GB(this->Next(), 0, 16) * max >> 16;
+	return ((uint64)this->Next() * (uint64)max) >> 32;
 }
 
 void Randomizer::SetSeed(uint32 seed)
@@ -55,9 +55,8 @@
 	return _random.Next();
 }
 
-uint DoRandomRange(uint max, int line, const char *file)
+uint32 DoRandomRange(uint32 max, int line, const char *file)
 {
-	assert(max <= UINT16_MAX);
-	return GB(DoRandom(line, file), 0, 16) * max >> 16;
+	return ((uint64)DoRandom(line, file) * (uint64)max) >> 32;
 }
 #endif /* RANDOM_DEBUG */
--- a/src/core/random_func.hpp
+++ b/src/core/random_func.hpp
@@ -48,7 +48,7 @@
 	 * @param max the maximum value of the returned random number
 	 * @return the random number
 	 */
-	uint32 Next(uint16 max);
+	uint32 Next(uint32 max);
 
 	/**
 	 * (Re)set the state of the random number generator.
@@ -92,16 +92,15 @@
 	#endif
 	uint32 DoRandom(int line, const char *file);
 	#define RandomRange(max) DoRandomRange(max, __LINE__, __FILE__)
-	uint DoRandomRange(uint max, int line, const char *file);
+	uint32 DoRandomRange(uint32 max, int line, const char *file);
 #else
 	static FORCEINLINE uint32 Random()
 	{
 		return _random.Next();
 	}
 
-	static FORCEINLINE uint32 RandomRange(uint max)
+	static FORCEINLINE uint32 RandomRange(uint32 max)
 	{
-		assert(max <= UINT16_MAX);
 		return _random.Next(max);
 	}
 #endif
@@ -111,7 +110,7 @@
 	return _interactive_random.Next();
 }
 
-static FORCEINLINE uint32 InteractiveRandomRange(uint16 max)
+static FORCEINLINE uint32 InteractiveRandomRange(uint32 max)
 {
 	return _interactive_random.Next(max);
 }
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -1923,8 +1923,7 @@
 
 	/* Add the remaining industries according to their probabilities */
 	for (uint i = 0; i < total_amount; i++) {
-		/* RandomRange() can only deal with 16 bit, which is not enough here. */
-		uint32 r = ((uint64)Random() * (uint64)total_prob) >> 32;
+		uint32 r = RandomRange(total_prob);
 		IndustryType it = 0;
 		while (it < NUM_INDUSTRYTYPES && r >= industry_probs[it]) {
 			r -= industry_probs[it];