Jump to content

Recommended Posts

Posted (edited)
#include <math.h>
#include <stdio.h>

typedef unsigned __int64 uint64;

#define TRUE 1
#define FALSE 0

#define INC 3
#define NEW 7
#define SEQUEL 9

class rnd64
{
   public:

   rnd64(void);
   ~rnd64(void);
   uint64 rnd(void);

   private:

   int prime_number(int);
   uint64 next(void);

   int status;
   uint64 dx;
   uint64 dy;
   uint64 end;
   uint64 x, y;
   uint64 R16A;
   uint64 R16B;
   uint64 Z[2];
   uint64 increaseA;
   uint64 increaseB;
};

rnd64::rnd64(void)
{
   dx=0xfedca201L;
   dy=0x012357bfL;
   R16A=(uint64)1;
   R16B=(uint64)2;
   Z[0]=Z[1]=0x00;
   x=5; y=3; end=2;
   increaseA=0x012357bfL;
   increaseB=0xfedca201L;
}

rnd64::~rnd64(void)
{
}

int rnd64::prime_number(int st)
{
   if (st == INC)
   {
      x+=2; y=3;
      if (x>=(1<<16)) x=5;
      end=unsigned(sqrt(double(x)+0.25));
      return SEQUEL;
   }
   else
   {
      if (!(x%y)) return FALSE;
      if ((y+=2)>end) return TRUE;
      return SEQUEL;
   }
}

inline uint64 uabs(uint64 &a, uint64 &b)
{
   return a>b? a-b: b-a;
}

inline void swap(uint64 &a, uint64 &b)
{
   uint64 c=a; a=b; b=c;
}

uint64 rnd64::next(void)
{
   status=prime_number(NEW);
   if (status == TRUE)
   {
      increaseB-=increaseA;
      increaseA+=x;
      prime_number(INC);
   }
   else if (status == FALSE)
   {
      prime_number(INC);
   }

   R16A -= increaseA; increaseA-=dx;
   R16B += increaseB; increaseB+=dy;

   if (status==TRUE)
   swap(R16A, R16B);

   R16A += (R16A>>32)^(R16B<<32);
   R16B -= (R16A<<32)^(R16B>>32);

   return R16A^R16B;
}

uint64 rnd64::rnd(void)
{
   uint64 p1=next();
   if (status==TRUE)
   {
      uint64 a[2], b[2];
      uint64 p2=next();
      a[0]=b[0] = Z[0];
      a[1]=b[1] = Z[1];
      ++a[unsigned(p1%2)];
      ++b[unsigned(p2%2)];
      uint64 A=uabs(a[0], a[1]);
      uint64 B=uabs(b[0], b[1]);

      if (Z[0] == Z[1])
      {
         if (unsigned(next()%2))
         {
            A=1; B=0;
         }
         else
         {
            A=0; B=1;
         }
      }

      if (A < B)
      {
         ++Z[unsigned(p1%2)];
         return p1;
      }
      else
      {
         ++Z[unsigned(p2%2)];
         return p2;
      }
   }
   else
   {
      ++Z[unsigned(p1%2)];
      return p1;
   }
}

void main(void)
{
   rnd64 R;
   int st=0;
   uint64 bit[2];
   bit[0]=bit[1]=0x00;

   for (;;)
   {
      uint64 P=R.rnd();
      ++bit[unsigned(P%2)];
      if (st==0 && bit[1]>bit[0])
      {
         printf("%d", bit[0]>bit[1]? 1: 0);
         st=1;
      }
      else if (st==1 && bit[0]>bit[1])
      {
         printf("%d", bit[0]>bit[1]? 1: 0);
         st=0;
      }
   }
}

 

Edited by Passenger
Testing

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.