struct table
{
long c_val;
short i_ind;
short j_ind;
float uni_tabl[TAB_SIZE];
};
/* This function creates the 97 row table of floating values which is used later in the UNI function. The table UNI_TABL is saved in a non-printable file along with 3 array counters, C_VAL, I_IND, and J_IND. This file will be read in again in the UNI function each time that the calling program needs a new random number. The table, I_IND, and J_IND are all modified in the UNI function and saved to the file upon exit so that the changed contents of the file can be read back in when the next random number is requested by the calling program. */
int set_uni(params)
int params;
{
short i, j, k, l;
struct table table_str;
register int i1, j1;
long rem, rem1;
unsigned long sum;
FILE *t_ptr;
short status = 0;
/* This file is used to store the table. It is read back into the UNI function later. */
if ((t_ptr = fopen(RAND_TABLE, "w+")) == NULL)
{
/* fprintf(stderr, "Can't create rtable for writing\n");*/
status = -1;
}
else /* rtable open for writing */
{
if (params == 4)
{
popshort(&l); /* pop seed numbers off the stack */
popshort(&k);
popshort(&j);
popshort(&i);
/**************************************************************/
/* This section is from the original C program on the Targon. */
/* The logic has not been modified at all. */
for (i1 = 0; i1 < TAB_SIZE ; i1++)
{
sum = 0;
for (j1 = NO_OF_BITS; j1 > 0; j1--) {
rem1 = (long)((i * j) % MOD_1);
rem1 = (long)((rem1 * k) % MOD_1);
i = j;
j = k;
k = (short)rem1;
rem = (long)(((CONST_1 * l) + 1) % MOD_2);
l = rem;
sum *= 2;
rem = (long)((l*rem1) % 64);
if (rem >= CONST_6)
sum += 1;
}
table_str.uni_tabl[i1] = sum;
}
table_str.c_val = CONST_2;
table_str.i_ind = CONST_5;
table_str.j_ind = CONST_6;
/* */
/*************************************************************/
/* Now save the table to a file so it can be read in later. */
fwrite (&table_str, sizeof(table_str),1,t_ptr);
fclose (t_ptr);
}
else /* 4 parameters were not passed to function */
{
status = -2;
}
}
retshort(status); /* Push the status onto the stack. This lets the */
return(1); /* calling 4gl know if the C function executed. */
}
/* This function reads in table from the file, gets the next random number, and then saves the new modified record. */
int uni(int params)
{
struct table table_str;
long uni_val;
FILE *t_ptr;
double uni_num;
long voter_number;
long stemp = 0;
short status = 0;
if ((t_ptr = fopen(RAND_TABLE, "r+")) == NULL)
{
/* fprintf(stderr, "Can't open randtable for read update\n");*/
status = -3;
}
else /* File opened for read */
{
if (params == 1) /* 1 parameter passed to function */
{
poplong(&voter_number); /* Pop voter reg number off of stack */
fread (&table_str, sizeof(table_str),1,t_ptr); /* Read table */
/*************************************************************/
/* This section is from the original C program on the Targon */
/* The logic has not been modified at all. */
/*************************************************************/
/* Now rewind the file, save the table, close the file, and return to the calling program. */
rewind(t_ptr);
fwrite (&table_str, sizeof(table_str),1,t_ptr);
fclose (t_ptr);
/* Calculate random number */
stemp = (long) ((uni_val / CONST_7) * voter_number) + 1;
}
else /* 1 parameter was not passed to function */
{
status = -4;
}
}
retlong(stemp); /* Push random number onto stack and*/
retshort(status); /* push status onto stack for 4gl */
return(2);
}