(snip of some suggestions, including a sign error in a shift)
I guess you didn't test this. I did, and it gives results that are different
from those given by the C code that George posted. The workaround that I
posted, in which the comparison of t and x is done laboriously:
(snip)
gives results identical to the C code. Can you supply Fortran
code that reproduces George's numbers?
Trying it with gcc, I don't get the same answers as George.
The following Fortran, modulo 2**32, gives the right answers:
The C code has been left in as comments. The before and after
comments removed, but one could add them back in from the original
post.
As mentioned previously, this assumes 32 bit, twos complement, and
that on overflow the proper low order bits are returned.
I haven't done any timing, or time comparisons to C.
integer function MWC()
! when did zero argument functions get added to Fortran?
integer q
common q(0:4690)
integer t,x,c,j
save c
data j/4691/
! unsigned long t,x,i; static c=0,j=4691;
j=j+1
if(j>4690) j=0
! j=(j<4690)? j+1:0;
x=q(j)
! x=Q[j];
t=ishft(x,13)+c+x
c=ishft(x,-19)
if(ieor(t,ishft(1,31)).lt.ieor(x,ishft(1,31))) c=c+1
! t=(x<<13)+c+x; c=(t<x)+(x>>19);
q(j)=t
MWC=t
return
end
! return (Q[j]=t);
! int main()
program main
integer xs,xcng
data xs,xcng/521288629,362436069/
! static unsigned long xs=521288629,xcng=362436069,Q[4691];
integer i,x
integer q
common q(0:4690)
! {unsigned long i,x;
do i=0,4690
xcng=69069*xcng+123
! #define CNG ( xcng=69069*xcng+123 )
xs=ieor(xs,ishft(xs, 13))
xs=ieor(xs,ishft(xs,-17))
xs=ieor(xs,ishft(xs, 5))
! #define XS ( xs^=(xs<<13), xs^=(xs>>17), xs^=(xs<<5) )
q(i)=xcng+xs
enddo
! for(i=0;i<4691;i++) Q
=CNG+XS;
do i=1,1000000000
x=MWC()
enddo
! for(i=0;i<1000000000;i++) x=MWC();
print *," MWC result=3740121002 (or -554846295) ?",x
! printf(" MWC result=3740121002 ?\n%22u\n",x);
! for(i=0;i<1000000000;i++) x=KISS;
do i=1,1000000000
xcng=69069*xcng+123
! #define CNG ( xcng=69069*xcng+123 )
xs=ieor(xs,ishft(xs, 13))
xs=ieor(xs,ishft(xs,-17))
xs=ieor(xs,ishft(xs, 5))
! #define XS ( xs^=(xs<<13), xs^=(xs>>17), xs^=(xs<<5) )
x=MWC()+xcng+xs
enddo
! #define KISS ( MWC()+CNG+XS ) /*138 million/sec*/
print *,"KISS result=2224631993 (or -2070335303) ?",x;
! printf("KISS result=2224631993 ?\n%22u\n",x);
! }
end
-- glen