Base: Fixed shift amount in genrand() to work with large numbers
authorDam Sunwoo <dam.sunwoo@arm.com>
Tue, 10 Jan 2012 00:08:20 +0000 (18:08 -0600)
committerDam Sunwoo <dam.sunwoo@arm.com>
Tue, 10 Jan 2012 00:08:20 +0000 (18:08 -0600)
The previous version didn't work correctly with max integer values (2^31-1 for
32-bit, 2^63-1 for 64bit version), causing "shift" to become -1.  For smaller
numbers, it wouldn't have caused functional errors, but would have resulted in
more than necessary loops in the while loop.  Special-cased cases when (max + 1
== 0) to prevent the ceilLog2 functions from failing.

src/base/random.cc

index 457b0c98be3115cfc6d17e669ae012742c1c34f6..cffeddec95927d049d1f19a83b88ae813b21edaa 100644 (file)
@@ -29,6 +29,7 @@
  *          Ali Saidi
  */
 
+#include <limits>
 #include "base/fenv.hh"
 #include "base/intmath.hh"
 #include "base/misc.hh"
@@ -67,7 +68,10 @@ Random::genrand(uint32_t max)
 {
     if (max == 0)
         return 0;
-    int log = ceilLog2(max) + 1;
+    if (max == std::numeric_limits<uint32_t>::max())
+        return genrand();
+
+    int log = ceilLog2(max + 1);
     int shift = (sizeof(uint32_t) * 8 - log);
     uint32_t random;
 
@@ -83,7 +87,10 @@ Random::genrand(uint64_t max)
 {
     if (max == 0)
         return 0;
-    int log = ceilLog2(max) + 1;
+    if (max == std::numeric_limits<uint64_t>::max())
+        return genrand();
+
+    int log = ceilLog2(max + 1);
     int shift = (sizeof(uint64_t) * 8 - log);
     uint64_t random;