about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-04-26 21:57:35 -0700
committerbors <bors@rust-lang.org>2013-04-26 21:57:35 -0700
commit8804b13bd2d7230f65db2c847177969dde9e3936 (patch)
tree3f53c886cbca97e43fbf32bda921828c99815d0a /src/rt
parent7c1696b5293370d1ecf563df23b6bb491f17a541 (diff)
parent1fc8a2f2a45c21247f6d0209ecb6349a2c20e453 (diff)
downloadrust-8804b13bd2d7230f65db2c847177969dde9e3936.tar.gz
rust-8804b13bd2d7230f65db2c847177969dde9e3936.zip
auto merge of #6058 : huonw/rust/rt-isaac-update, r=graydon
The "unsigned 4 byte" `ub4`s are actually 8 bytes on 64-bit platforms
which mean that some bits > 2**32 were retained in calculations, these
would then "reappear" after a right shift and so the stream of random numbers
would differ on 32 bit vs 64 bit platforms.

http://burtleburtle.net/bob/c/randport.c
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/isaac/randport.cpp41
-rw-r--r--src/rt/isaac/standard.h23
2 files changed, 37 insertions, 27 deletions
diff --git a/src/rt/isaac/randport.cpp b/src/rt/isaac/randport.cpp
index 5b40506f856..a2928a9b5d0 100644
--- a/src/rt/isaac/randport.cpp
+++ b/src/rt/isaac/randport.cpp
@@ -6,6 +6,7 @@ MODIFIED:
   970719: use context, not global variables, for internal state
   980324: make a portable version
   010626: Note this is public domain
+  100725: Mask on use of >32 bits, not on assignment: from Paul Eggert
 ------------------------------------------------------------------------------
 */
 #ifndef STANDARD
@@ -27,22 +28,22 @@ MODIFIED:
 
 void     isaac(randctx *ctx)
 {
-   register ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
+   ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
    mm=ctx->randmem; r=ctx->randrsl;
-   a = ctx->randa; b = (ctx->randb + (++ctx->randc)) & 0xffffffff;
+   a = ctx->randa; b = ctx->randb + (++ctx->randc);
    for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
    {
       rngstep( a<<13, a, b, mm, m, m2, r, x);
-      rngstep( a>>6 , a, b, mm, m, m2, r, x);
+      rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
       rngstep( a<<2 , a, b, mm, m, m2, r, x);
-      rngstep( a>>16, a, b, mm, m, m2, r, x);
+      rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
    }
    for (m2 = mm; m2<mend; )
    {
       rngstep( a<<13, a, b, mm, m, m2, r, x);
-      rngstep( a>>6 , a, b, mm, m, m2, r, x);
+      rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
       rngstep( a<<2 , a, b, mm, m, m2, r, x);
-      rngstep( a>>16, a, b, mm, m, m2, r, x);
+      rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
    }
    ctx->randb = b; ctx->randa = a;
 }
@@ -50,14 +51,14 @@ void     isaac(randctx *ctx)
 
 #define mix(a,b,c,d,e,f,g,h) \
 { \
-   a^=b<<11; d+=a; b+=c; \
-   b^=c>>2;  e+=b; c+=d; \
-   c^=d<<8;  f+=c; d+=e; \
-   d^=e>>16; g+=d; e+=f; \
-   e^=f<<10; h+=e; f+=g; \
-   f^=g>>4;  a+=f; g+=h; \
-   g^=h<<8;  b+=g; h+=a; \
-   h^=a>>9;  c+=h; a+=b; \
+   a^=b<<11;              d+=a; b+=c; \
+   b^=(c&0xffffffff)>>2;  e+=b; c+=d; \
+   c^=d<<8;               f+=c; d+=e; \
+   d^=(e&0xffffffff)>>16; g+=d; e+=f; \
+   e^=f<<10;              h+=e; f+=g; \
+   f^=(g&0xffffffff)>>4;  a+=f; g+=h; \
+   g^=h<<8;               b+=g; h+=a; \
+   h^=(a&0xffffffff)>>9;  c+=h; a+=b; \
 }
 
 /* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
@@ -81,8 +82,10 @@ void randinit(randctx *ctx, word flag)
      /* initialize using the contents of r[] as the seed */
      for (i=0; i<RANDSIZ; i+=8)
      {
-       a+=r[i  ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3];
-       e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7];
+       a+=r[i  ]; b+=r[i+1];
+       c+=r[i+2]; d+=r[i+3];
+       e+=r[i+4]; f+=r[i+5];
+       g+=r[i+6]; h+=r[i+7];
        mix(a,b,c,d,e,f,g,h);
        m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
        m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
@@ -90,8 +93,10 @@ void randinit(randctx *ctx, word flag)
      /* do a second pass to make all of the seed affect all of m */
      for (i=0; i<RANDSIZ; i+=8)
      {
-       a+=m[i  ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3];
-       e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7];
+       a+=m[i  ]; b+=m[i+1];
+       c+=m[i+2]; d+=m[i+3];
+       e+=m[i+4]; f+=m[i+5];
+       g+=m[i+6]; h+=m[i+7];
        mix(a,b,c,d,e,f,g,h);
        m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
        m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
diff --git a/src/rt/isaac/standard.h b/src/rt/isaac/standard.h
index cb6cc15b8f6..c196a37474b 100644
--- a/src/rt/isaac/standard.h
+++ b/src/rt/isaac/standard.h
@@ -13,27 +13,32 @@ Standard definitions and types, Bob Jenkins
 #  include <stddef.h>
 #  define STDDEF
 # endif
-typedef  unsigned long long  ub8;
+# ifndef STDINT
+#  include <stdint.h>
+#  define STDINT
+# endif
+
+typedef  uint64_t  ub8;
 #define UB8MAXVAL 0xffffffffffffffffLL
 #define UB8BITS 64
-typedef    signed long long  sb8;
+typedef   int64_t  sb8;
 #define SB8MAXVAL 0x7fffffffffffffffLL
-typedef  unsigned long  int  ub4;   /* unsigned 4-byte quantities */
+typedef  uint32_t  ub4;   /* unsigned 4-byte quantities */
 #define UB4MAXVAL 0xffffffff
-typedef    signed long  int  sb4;
+typedef   int32_t  sb4;
 #define UB4BITS 32
 #define SB4MAXVAL 0x7fffffff
-typedef  unsigned short int  ub2;
+typedef  uint16_t  ub2;
 #define UB2MAXVAL 0xffff
 #define UB2BITS 16
-typedef    signed short int  sb2;
+typedef   int16_t  sb2;
 #define SB2MAXVAL 0x7fff
-typedef  unsigned       char ub1;
+typedef   uint8_t  ub1;
 #define UB1MAXVAL 0xff
 #define UB1BITS 8
-typedef    signed       char sb1;   /* signed 1-byte quantities */
+typedef    int8_t  sb1;   /* signed 1-byte quantities */
 #define SB1MAXVAL 0x7f
-typedef                 int  word;  /* fastest type available */
+typedef      int  word;  /* fastest type available */
 
 #define bis(target,mask)  ((target) |=  (mask))
 #define bic(target,mask)  ((target) &= ~(mask))