/* 
   * Copyright (C) 2001-2003, CompHEP COllaboration
   *------------------------------------------------------
   * Restored version of standard drand48 and seed48 procedures 
   *
   * $Id: drandXX.c,v 1.1 2003/08/25 09:08:20 sherstnv Exp $
   *
   * $Log: drandXX.c,v $
   * Revision 1.1  2003/08/25 09:08:20  sherstnv
   * Files drandXX.c/h move num -> service2
   *
   * Revision 1.5  2003/06/25 18:46:41  kryukov
   * *** empty log message ***
   *
   * Revision 1.4  2003/04/22 09:01:18  kryukov
   * Apply indent to improve readability of files
   *
   * Revision 1.3  2003/04/20 17:55:02  kryukov
   * Clean up warnings during make
   *
 */
#include <stdlib.h>
#include <stdio.h>
#include "drandXX.h"

static double float48 = 1. / (((double) 0x10000) * ((double) 0x10000) * ((double) 0x10000));

static unsigned long Xlong = 0x1234ABCD;
static unsigned long Xshort = 0x330E;
#define Along   0x5DEEC
#define Ashort  0xE66D
#define Along16 0xDEEC0000
#define  Clong  0
#define  Cshort 0xB
#define FIRST16 0xFFFF


double 
drandXX (void)
{
  unsigned long bot = Xshort * Ashort;
  unsigned long top = Clong + (bot >> 16);

  bot = (bot & FIRST16) + Cshort;

  Xlong = top + (bot >> 16) + Along * Xshort + Ashort * Xlong + ((Along16 * Xlong));
  Xshort = bot & FIRST16;

  return ((double) Xshort + (Xlong & 0xFFFFFFFF) * (double) 0x10000) * float48;
}

char *
seedXX (char *init)
{
  unsigned long Xlong_, Xshort_;
  static char cbuff[128];
  static char frmt1[128];
  static char frmt2[128];
  int lenth = 2*sizeof(unsigned long);

  sprintf (frmt1, "%s%i%s", "%0", lenth, "lX%04lX");
  sprintf (frmt2, "%s%i%s", "%", lenth, "lX%4lX");

  sprintf (cbuff, frmt1, Xlong, Xshort);

  if (init)
    {
      if (sscanf (init, frmt2, &Xlong_, &Xshort_) == 2)
	{
	  Xlong = Xlong_;
	  Xshort = Xshort_;
	}
      else
	return NULL;
    }
  return cbuff;
}
