Make randomNumber generate 2^53 values instead of 2^32 (or 2^31 for rand() platforms)
[WebKit-https.git] / JavaScriptCore / wtf / RandomNumber.cpp
index 9b473e3..e569227 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- *           (C) 2008 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
+ *           (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,7 +29,9 @@
 
 #include "RandomNumberSeed.h"
 
+#include <limits>
 #include <limits.h>
+#include <stdint.h>
 #include <stdlib.h>
 
 namespace WTF {
@@ -43,15 +45,43 @@ double randomNumber()
         s_initialized = true;
     }
 #endif
-
+    
+    uint32_t part1;
+    uint32_t part2;
+    uint64_t fullRandom;
 #if COMPILER(MSVC) && defined(_CRT_RAND_S)
-    unsigned u;
-    rand_s(&u);
-
-    return static_cast<double>(u) / (static_cast<double>(UINT_MAX) + 1.0);
+    rand_s(&part1);
+    rand_s(&part2);
+    fullRandom = part1;
+    fullRandom <<= 32;
+    fullRandom |= part2;
+#elif PLATFORM(DARWIN)
+    part1 = arc4random();
+    part2 = arc4random();
+    fullRandom = part1;
+    fullRandom <<= 32;
+    fullRandom |= part2;
+#elif PLATFORM(UNIX)
+    part1 = random() & (RAND_MAX - 1);
+    part2 = random() & (RAND_MAX - 1);
+    // random only provides 31 bits
+    fullRandom = part1;
+    fullRandom <<= 31;
+    fullRandom |= part2;
 #else
-    return static_cast<double>(rand()) / (static_cast<double>(RAND_MAX) + 1.0);
+    part1 = rand() & (RAND_MAX - 1);
+    part2 = rand() & (RAND_MAX - 1);
+    // rand only provides 31 bits, and the low order bits of that aren't very random
+    // so we take the high 26 bits of part 1, and the high 27 bits of part2.
+    part1 >>= 5; // drop the low 5 bits
+    part2 >>= 4; // drop the low 4 bits
+    fullRandom = part1;
+    fullRandom <<= 27;
+    fullRandom |= part2;
 #endif
+    // Mask off the low 53bits
+    fullRandom &= (1LL << 53) - 1;
+    return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53);
 }
 
 }