]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Avoid signed integer overflow in Testing::rand 5560/head
authorDaniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Fri, 1 Dec 2017 13:50:59 +0000 (14:50 +0100)
committerDaniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Fri, 1 Dec 2017 13:50:59 +0000 (14:50 +0100)
tests/tests.h

index 84da785348b277828b71000eb47caff653c09c06..eb4212e8f4138a7fb40500e9e851d227ba436ab7 100644 (file)
@@ -146,16 +146,24 @@ namespace Testing
     static int r[32];
     static int k;
     static bool inited=false;
+
     if (!inited || reseed)
       {
         //srand treats a seed 0 as 1 for some reason
         r[0]=(seed==0)?1:seed;
+        long int word = r[0];
 
         for (int i=1; i<31; i++)
           {
-            r[i] = (16807LL * r[i-1]) % 2147483647;
-            if (r[i] < 0)
-              r[i] += 2147483647;
+            // This does:
+            //   r[i] = (16807 * r[i-1]) % 2147483647;
+            // buit avoids overflowing 31 bits.
+            const long int hi = word / 127773;
+            const long int lo = word % 127773;
+            word = 16807 * lo - 2836 * hi;
+            if (word < 0)
+              word += 2147483647;
+            r[i] = word;
           }
         k=31;
         for (int i=31; i<34; i++)
@@ -180,7 +188,7 @@ namespace Testing
     return (unsigned int)ret >> 1;
   }
 
-// reseed our random number generator
+  // reseed our random number generator
   void srand(const int seed)
   {
     rand(true, seed);

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.