RandomRDRand.st
changeset 4926 0d707ba99ea5
parent 4925 3b6b894d2664
child 4927 8e944da8fc20
--- a/RandomRDRand.st	Thu Mar 28 11:08:37 2019 +0100
+++ b/RandomRDRand.st	Thu Mar 28 11:35:23 2019 +0100
@@ -16,7 +16,7 @@
 "{ NameSpace: Smalltalk }"
 
 Object subclass:#RandomRDRand
-	instanceVariableNames:'x y z c'
+	instanceVariableNames:''
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Magnitude-Numbers-Random'
@@ -104,6 +104,9 @@
 
 !RandomRDRand methodsFor:'initialization'!
 
+initialize
+!
+
 seed:seed
     "/ ignored
 ! !
@@ -113,11 +116,22 @@
 nextBoolean
     "generates a boolean random"
 
-    ^ self nextInteger > 16r7FFFFFFF
+    ^ self nextInteger odd
+
+    "
+        |bag rng|
+
+        rng := self new.
+        bag := Bag new.
+        100000 timesRepeat:[
+            bag add:rng nextBoolean.
+        ].
+        bag
+    "
 !
 
 nextInteger
-    "generates the next integer in 0..FFFFFFFF.
+    "generates the next integer in 0..MAXINT.
      Notice, it may raise an illegal instruction exception on some cpu chips,
      even though the cpuid instruction says that it is available"
 
@@ -125,7 +139,7 @@
 
 %{
     unsigned INT r = 0;
-    int cf;
+    unsigned char cf;
     int count = 50;
 
     do {
@@ -135,14 +149,14 @@
         cf = _rdrand32_step(&r);
 #elif defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
         // Encoding of rdrand %eax
-        asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1"
+        asm(".byte 0x0F, 0xC7, 0xF0; setc %1"
             : "=a" (r), "=r" (cf)
             : "0" (r), "1" (cf)
             : "cc");
 
 #elif defined(__x86_64__) && defined(__GNUC__) && (__GNUC__ >= 2)
         // Encoding of rdrand %rax
-        asm(".byte 0x48, 0x0F, 0xC7, 0xF0; adcl $0,%1"
+        asm(".byte 0x48, 0x0F, 0xC7, 0xF0; setc %1"
             : "=a" (r), "=r" (cf)
             : "0" (r), "1" (cf)
             : "cc");
@@ -150,15 +164,15 @@
 #else
         goto unsupported;
 #endif
-    } while ((cf != 0) && (--count > 0));
-    if (cf == 0) {
+    } while ((cf == 0) && (--count > 0));
+    if (cf != 0) {
         RETURN (__MKUINT(r));
     }
     cfStillSet = true;
 unsupported: ;
 %}.
     cfStillSet == true ifTrue:[
-        self primitiveFailed:'carry flag not clear after 50 tries'
+        self primitiveFailed:'carry flag not clear after 500 tries'
     ].
     self primitiveFailed:'unsupported on this architecture'