Hi friends,

I need to convert this random number generator in C++ to C. Please help me.

C++ code

#include <iostream>
#include <ctime>
using namespace std;

//This class will give satisfy basic
// random number considerations for
// games an general apps.
// WARNING: Not for Cryprographic use
//   Not for statistical methods.
class BasicLCG {
	
	private:
		unsigned long iCurrent;
	public:
		BasicLCG();
		BasicLCG(unsigned long);
		void seed(unsigned long iSeed);
		unsigned long nextNumber(); //get the next random number
		unsigned short int nextInt();
		unsigned char nextChar();
		int nextBit();
		double nextDouble();
		int inRange(int min, int max);
};


//Just a little test code to print some numbers
int main()
{
	BasicLCG rng(time(NULL));
	int i;
	//Lets see some bits...
//	for( i=1; i<81; i++) {
//		cout << rng.nextBit() <<"\t";
//	}
//	cout <<"\n";
//	for( i=1; i<41; i++) {
//		cout << (int)rng.nextChar() <<"\t";
//	}
//	cout <<"\n";
//	for( i=1; i<41; i++) {
//		cout << rng.nextInt() <<"\t";
//	}
//	cout <<"\n";
//	for( i=1; i<41; i++) {
//		cout << rng.nextNumber() <<"\t";
//	}
//	cout <<"\n\n";
//	for( i=1; i<41; i++) {
//		cout << rng.nextDouble() <<"\t";
//	}
//	cout <<"\n\n";
	for( i=1; i<7; i++) {
		cout << rng.inRange(0, 7) <<"\n";
	}

	return 0;
}

BasicLCG::BasicLCG()
{
	iCurrent = 0; //Chose a default seed 
}

BasicLCG::BasicLCG(unsigned long iSeed)
{
	iCurrent = iSeed;
}

void BasicLCG::seed(unsigned long iSeed)
{
	iCurrent = iSeed;
}

//NOTE: a and c are selected for no particular properties
// and I have not run statistical tests on this number gernerator
// it is was written for demonstration purposes only.
unsigned long BasicLCG::nextNumber()
{
	unsigned long iOutput;
	unsigned long iTemp;
	int i;
	//I only want to take the top two bits
	//This will shorten our period to (2^32)/16=268,435,456
	//Which seems like plenty to me.
	for(i=0; i<16; i++)
	{
		//Since this is mod 2^32 and our data type is 32 bits long
		// there is no need for the MOD operator.
		iCurrent = (3039177861 * iCurrent + 1);
		iTemp = iCurrent >> 30;
		iOutput = iOutput << 2;
		iOutput = iOutput + iTemp;
	}
	return iOutput;	
}

unsigned short int BasicLCG::nextInt()
{
	unsigned short int iOutput;
	unsigned long iTemp;
	int i;
	//No need to limit ourselves...
	for(i=0; i<8; i++)
	{
		//Since this is mod 2^32 and our data type is 32 bits long
		// there is no need for the MOD operator.
		iCurrent = (3039177861 * iCurrent + 1);
		iTemp = iCurrent >> 30;
		iOutput = iOutput << 2;
		iOutput = iOutput + (short int)iTemp;
	}
	return iOutput;	
}

unsigned char BasicLCG::nextChar()
{
	unsigned char cOutput;
	unsigned long iTemp;
	int i;
	for(i=0; i<4; i++)
	{
		iCurrent = (3039177861 * iCurrent + 1);
		iTemp = iCurrent >> 30;
		cOutput = cOutput << 2;
		cOutput = cOutput + (char)iTemp;
	}
	return cOutput;	
}

int BasicLCG::nextBit()
{
	iCurrent = (3039177861 * iCurrent + 1);
	return iCurrent >> 31;	 
}

double BasicLCG::nextDouble()
{
	return (double)nextNumber()/0xFFFFFFFF;
}

int BasicLCG::inRange(int iMin, int iMax)
{
	int Diff;
	//IF the user put them in backwards then swap them
	if (iMax<iMin)
	{ 
		//Integer swap
		iMax = iMax ^ iMin; //iMax holds iMax ^ iMin
		iMin = iMax ^ iMin; //iMin= (iMax ^ iMin) ^ iMin = iMax (original)
		iMax = iMax ^ iMin; //iMax= (iMax ^ iMin) ^ iMax = iMin (original)
	}
	Diff = iMax - iMin + 1;
	return (int) (nextDouble()*Diff)+iMin;
}

I did (have errors):

/*#include <iostream>*/
/*#include <ctime>*/
/*using namespace std;*/

#include <time.h>
#include <stdio.h>


/*class BasicLCG {*/
/*	*/
/*	private:*/
/*		unsigned long iCurrent;*/
/*	public:*/
/*		BasicLCG();*/
/*		BasicLCG(unsigned long);*/
/*		void seed(unsigned long iSeed);*/
/*		unsigned long nextNumber(); //get the next random number*/
/*		unsigned short int nextInt();*/
/*		unsigned char nextChar();*/
/*		int nextBit();*/
/*		double nextDouble();*/
/*		int inRange(int min, int max);*/
/*};*/

unsigned long iCurrent;
BasicLCG();
BasicLCG(unsigned long);
void seed(unsigned long iSeed);
unsigned long nextNumber(); //get the next random number
unsigned short int nextInt();
unsigned char nextChar();
int nextBit();
double nextDouble();
int inRange(int min, int max);


//Just a little test code to print some numbers
int main()
{
/*	BasicLCG rng(time(NULL));*/

	rng(time(0));

	int i;

	for( i=1; i<7; i++) {
/*		cout << rng.inRange(0, 7) <<"\n";*/

		printf("%d", inRange(0,7));
	}

	return 0;
}


/*BasicLCG::BasicLCG()*/
/*{*/
/*	iCurrent = 0; //Chose a default seed */
/*}*/

BasicLCG()
{
	iCurrent = 0; //Chose a default seed 
}


/*BasicLCG::BasicLCG(unsigned long iSeed)*/
/*{*/
/*	iCurrent = iSeed;*/
/*}*/

BasicLCG(unsigned long iSeed)
{
	iCurrent = iSeed;
}

/*void BasicLCG::seed(unsigned long iSeed)*/
/*{*/
/*	iCurrent = iSeed;*/
/*}*/

void seed(unsigned long iSeed)
{
	iCurrent = iSeed;
}


/*unsigned long BasicLCG::nextNumber()*/
/*{*/
/*	unsigned long iOutput;*/
/*	unsigned long iTemp;*/
/*	int i;*/
/*	for(i=0; i<16; i++)*/
/*	{*/
/*		iCurrent = (3039177861 * iCurrent + 1);*/
/*		iTemp = iCurrent >> 30;*/
/*		iOutput = iOutput << 2;*/
/*		iOutput = iOutput + iTemp;*/
/*	}*/
/*	return iOutput;	*/
/*}*/


unsigned long nextNumber()
{
	unsigned long iOutput;
	unsigned long iTemp;
	int i;
	for(i=0; i<16; i++)
	{
		iCurrent = (3039177861 * iCurrent + 1);
		iTemp = iCurrent >> 30;
		iOutput = iOutput << 2;
		iOutput = iOutput + iTemp;
	}
	return iOutput;	
}


/*unsigned short int BasicLCG::nextInt()*/
/*{*/
/*	unsigned short int iOutput;*/
/*	unsigned long iTemp;*/
/*	int i;*/
/*	//No need to limit ourselves...*/
/*	for(i=0; i<8; i++)*/
/*	{*/
/*		//Since this is mod 2^32 and our data type is 32 bits long*/
/*		// there is no need for the MOD operator.*/
/*		iCurrent = (3039177861 * iCurrent + 1);*/
/*		iTemp = iCurrent >> 30;*/
/*		iOutput = iOutput << 2;*/
/*		iOutput = iOutput + (short int)iTemp;*/
/*	}*/
/*	return iOutput;	*/
/*}*/

/*unsigned char BasicLCG::nextChar()*/
/*{*/
/*	unsigned char cOutput;*/
/*	unsigned long iTemp;*/
/*	int i;*/
/*	for(i=0; i<4; i++)*/
/*	{*/
/*		iCurrent = (3039177861 * iCurrent + 1);*/
/*		iTemp = iCurrent >> 30;*/
/*		cOutput = cOutput << 2;*/
/*		cOutput = cOutput + (char)iTemp;*/
/*	}*/
/*	return cOutput;	*/
/*}*/

/*int BasicLCG::nextBit()*/
/*{*/
/*	iCurrent = (3039177861 * iCurrent + 1);*/
/*	return iCurrent >> 31;	 */
/*}*/


/*double BasicLCG::nextDouble()*/
/*{*/
/*	return (double)nextNumber()/0xFFFFFFFF;*/
/*}*/


double nextDouble()
{
	return (double)nextNumber()/0xFFFFFFFF;
}


/*int BasicLCG::inRange(int iMin, int iMax)*/
/*{*/
/*	int Diff;*/
/*	//IF the user put them in backwards then swap them*/
/*	if (iMax<iMin)*/
/*	{ */
/*		//Integer swap*/
/*		iMax = iMax ^ iMin; //iMax holds iMax ^ iMin*/
/*		iMin = iMax ^ iMin; //iMin= (iMax ^ iMin) ^ iMin = iMax (original)*/
/*		iMax = iMax ^ iMin; //iMax= (iMax ^ iMin) ^ iMax = iMin (original)*/
/*	}*/
/*	Diff = iMax - iMin + 1;*/
/*	return (int) (nextDouble()*Diff)+iMin;*/
/*}*/


int inRange(int iMin, int iMax)
{
	int Diff;

	if (iMax<iMin)
	{ 
		//Integer swap
		iMax = iMax ^ iMin; //iMax holds iMax ^ iMin
		iMin = iMax ^ iMin; //iMin= (iMax ^ iMin) ^ iMin = iMax (original)
		iMax = iMax ^ iMin; //iMax= (iMax ^ iMin) ^ iMax = iMin (original)
	}
	Diff = iMax - iMin + 1;
	return (int) (nextDouble()*Diff)+iMin;
}

erros when I compile my C code:

randcpp.c:26: warning: data definition has no type or storage class
randcpp.c:27: warning: data definition has no type or storage class
randcpp.c: In function 'BasicLCG':
randcpp.c:62: error: number of arguments doesn't match prototype
randcpp.c:27: error: prototype declaration
randcpp.c: At top level:
randcpp.c:72: error: redefinition of 'BasicLCG'
randcpp.c:62: error: previous definition of 'BasicLCG' was here
randcpp.c: In function 'nextNumber':
randcpp.c:111: warning: this decimal constant is unsigned only in ISO C90

add return type for BasicLCG(); and BasicLCG(unsigned long); It should solve you first 4 compilation error

add return type for BasicLCG(); and BasicLCG(unsigned long); It should solve you first 4 compilation error

Yes, but it does nothing for the redeclaration error immediately below it. C doesn't allow function overloading; you'll need to give the two different functions different names. Furthermore, those two functions are constructors in the original; there's no fixed equivalent of that in C.

hairo: If you don't mind me asking, why are you converting C++ code to C in the first place? Unlike going in the other direction, there are substantial problems in doing this, and probably little to be gained. What is this for? You might be better off writing the C version from scratch, just using the random number algorithm but writing new code.

Edited 5 Years Ago by Schol-R-LEA: n/a

Comments

Hi Schoil-R-LEA,

Thank you for your reply.

I'm designing a hardware consists of a processor downloaded from opencore. The problem is I cannot use built in rand() in C because it did not fit in my 2KB instruction memory. So I search for random generator code and found that in C++, then need to convert it to C code because I'm using gcc compiler to convert the elf file to verilog memory format to load the instruction.

Ok thanks for your suggestion.

Hairo

This article has been dead for over six months. Start a new discussion instead.