can anybody convert this java into Blitz3D

Blitz3D Forums/Blitz3D Programming/can anybody convert this java into Blitz3D

import java.util.Date;

public class BD4Rand {

	private long seed;
	private long mult;
	public int add = 0x0000b;

	public BD4Rand(long s) {
		srand48(s);
	}

	public void srand48() {
		Date d = new Date();
		srand48(d.getTime());
	}
	public void srand48(long set_seed) {
		long tmp		= 0x0005de;
		this.mult	= (tmp<<24)+0xece66d;
		this.seed	= (set_seed<<16)+0x330e;
	}

	public double nextDouble() {
		long accu,t1,t0;

		accu = (this.mult&0xFFFF) * (this.seed&0xFFFF) + add;

		t0 = (accu&0xFFFF);
		accu >>= 16;
		accu += (this.mult&0xFFFF) * ((this.seed>>16)&0xFFFF) +
					((this.mult>>16)&0xFFFF)*(this.seed&0xFFFF);
		t1 = (accu&0xFFFF);
		accu >>= 16;
		accu += (this.mult&0xFFFF) * ((this.seed>>32)&0xFFFF) +
					((this.mult>>16)&0xFFFF)*((this.seed>>16)&0xFFFF) +
					((this.mult>>32)&0xFFFF)*(this.seed&0xFFFF);

		this.seed = ((accu&0xFFFF)<<32) + (t1<<16) + t0;

		return this.seed*java.lang.Math.pow(2,-48);
	}

}


i just can't get my head into this java any help would be much appreciated, its supposed to be a random number generator, yeah i know blitz has one but this has to match this code so games in both languages are compatible....

Ian

Well .. I did my best. Not sure if it works though, because I don't know how it should work, but maybe you can finetune it:

Type TBD4Rand

	Field seed
	Field mult
	Field add ;= 0x0000b
	
End Type

;-----------------------------------------------------------------------------------------------------
;                                                 CreateBD4()
;-----------------------------------------------------------------------------------------------------
Function CreateBD4.TBD4Rand()

	b.TBD4Rand = New TBD4Rand
	b\add = $0000B
	
End Function

;-----------------------------------------------------------------------------------------------------
;                                                   BD4Rand()
;-----------------------------------------------------------------------------------------------------
Function BD4Rand(b.TBD4Rand, s)

	Return SRand48(b, s)

End Function

;-----------------------------------------------------------------------------------------------------
;													SRand48()
;-----------------------------------------------------------------------------------------------------
Function SRand48(b.TBD4Rand, a$ = "NoP")

	If a$ = "NoP" Then
		Return SRand48_2(b, MilliSecs() )
	Else
		Return SRand48_2(b, set_seed)
	End If
	
End Function

;-----------------------------------------------------------------------------------------------------
; 												    SRand48_2()
;-----------------------------------------------------------------------------------------------------
Function SRand48_2(b.TBD4Rand, set_seed )

	Local tmp = $0005DE

	b\mult = (tmp Shl 24) + $ECE66D
	b\seed = (set_seed Shl 16) + $330E		


End Function

;-----------------------------------------------------------------------------------------------------
;                                                   nextDouble
;-----------------------------------------------------------------------------------------------------
Function nextDouble#(b.TBD4Rand)

	Local accu, t1, t0

	accu = (b\mult And $FFFF) * (b\seed And $FFFF) + add;

	t0 = (accu And $FFFF)
	accu = accu Shr 16;

	accu = accu + (b\mult And $FFFF) * ((b\seed Shr 16) And $FFFF) 
	accu = accu + ((b\mult Shr 16) And $FFFF)*(b\seed And $FFFF)
					
	t1 = (accu And $FFFF);

	accu = accu Shr 16;
	accu = accu + (b\mult And $FFFF) * ((b\seed Shr 32) And $FFFF)
	accu = accu + ((b\mult Shr 16) And $FFFF) * ((b\seed Shr 16) And $FFFF)
	accu = accu + ((b\mult Shr 32) And $FFFF) * (b\seed And $FFFF)

	b\seed = ((accu And $FFFF) Shl 32) + (t1 Shl 16) + t0

	Return b\seed * 0.0000000000000035527136788005009293556213378906
	;java.lang.Math.pow(2,-48) = 2^-48 = ?

End Function


Taking a quick look, I don't think it can be done. For a start, it's using long ints (64bit) which blitz doesn't support.

thanks for that b32, i'll check out your gamebuilder too....

this is a C version if it helps too make things clearer, just messes with my head...


#include <math.h>
#include <stdlib.h>

unsigned short bd4Rand48_seed[3] = { 0x330e, 0xabcd, 0x1234 };
unsigned short bd4Rand48_mult[3] = { 0xe66d, 0xdeec, 0x0005 };
unsigned short bd4Rand48_add = 0x000b;

void bd4srand(long seed)
{
	bd4Rand48_seed[0] = 0x330e;
	bd4Rand48_seed[1] = (unsigned short) seed;
	bd4Rand48_seed[2] = (unsigned short) (seed >> 16);
	bd4Rand48_mult[0] = 0xe66d;
	bd4Rand48_mult[1] = 0xdeec;
	bd4Rand48_mult[2] = 5;
	bd4Rand48_add = 0x000b;
}                                       

double bd4rand(void)
{ 
	unsigned long accu;
	unsigned short temp[2];

	accu = (unsigned long) bd4Rand48_mult[0] * (unsigned long) bd4Rand48_seed[0] +
	 (unsigned long) bd4Rand48_add;
	temp[0] = (unsigned short) accu;	/* lower 16 bits */
	accu >>= sizeof(unsigned short) * 8;
	accu += (unsigned long) bd4Rand48_mult[0] * (unsigned long) bd4Rand48_seed[1] +
	 (unsigned long) bd4Rand48_mult[1] * (unsigned long) bd4Rand48_seed[0];
	temp[1] = (unsigned short) accu;	/* middle 16 bits */
	accu >>= sizeof(unsigned short) * 8;
	accu += bd4Rand48_mult[0] * bd4Rand48_seed[2] + bd4Rand48_mult[1] * bd4Rand48_seed[1] + bd4Rand48_mult[2] * bd4Rand48_seed[0];
	bd4Rand48_seed[0] = temp[0];
	bd4Rand48_seed[1] = temp[1];
	bd4Rand48_seed[2] = (unsigned short) accu;

	return ldexp((double) bd4Rand48_seed[0], -48) +
	       ldexp((double) bd4Rand48_seed[1], -32) +
	       ldexp((double) bd4Rand48_seed[2], -16);
}

/**
 *		Basically copies a number of calls to a seeds drand48 with the "_add"
 *		variable changed from 0x0b==11 to 0x3d==61
 */
int bd4l(long key) {

	unsigned short bd4l_seed[3] = { 0x330e, 0xabcd, 0x1234 };
	unsigned short bd4l_mult[3] = { 0xe66d, 0xdeec, 0x0005 };
	unsigned short bd4l_add = 61; /* 0x000b;*/
	unsigned long accu;
	unsigned short temp[2];
	double tmp;
	int i;

	bd4l_seed[1] = (unsigned short) key;
	bd4l_seed[2] = (unsigned short) (key >> 16);

	/**
	 *		Repreat random "drand48-similar" loop 5-15 times.
	 *	
	 */
	for(i=-5;i<(key%10);i++) {
		accu = (unsigned long) bd4l_mult[0] * (unsigned long) bd4l_seed[0] +
	 	(unsigned long) bd4l_add;
		temp[0] = (unsigned short) accu;	/* lower 16 bits */
		accu >>= sizeof(unsigned short) * 8;
		accu += (unsigned long) bd4l_mult[0] * (unsigned long) bd4l_seed[1] +
	 	(unsigned long) bd4l_mult[1] * (unsigned long) bd4l_seed[0];
		temp[1] = (unsigned short) accu;	/* middle 16 bits */
		accu >>= sizeof(unsigned short) * 8;
		accu += bd4l_mult[0] * bd4l_seed[2] + bd4l_mult[1] * bd4l_seed[1] + bd4l_mult[2] * bd4l_seed[0];
		bd4l_seed[0] = temp[0];
		bd4l_seed[1] = temp[1];
		bd4l_seed[2] = (unsigned short) accu;
	}

	tmp = ldexp((double) bd4l_seed[0], -48) +
	       ldexp((double) bd4l_seed[1], -32) +
	       ldexp((double) bd4l_seed[2], -16);

	return 9787*tmp;
}




Are you sure that C conversion is accurate? Like Big10P I understood that longs in java are 64bit, whereas ( and I know my C is very rusty ) I thought C longs were 32 bit.

well that is from the same guy and it does the same job(i am told), i have no idea to tell the truth having no experience in either of the languages.

at a guess from what i have managaed to comprehend of the two he is only using the lower (16 bits)
and middle (16 bits) total of 32bits anyway, no idea if this is correct as i said i dont get it....

Here, I forgot to include 'return b' in the create function. And I made a test at the start of the program:

b.TBD4Rand = CreateBD4()
SRand48(b)

Print nextDouble(b)
Print nextDouble(b)
Print nextDouble(b)
Print nextDouble(b)
Print nextDouble(b)
Print nextDouble(b)
Print nextDouble(b)
Print nextDouble(b)



Type TBD4Rand

	Field seed
	Field mult
	Field add ;= 0x0000b
	
End Type

;-----------------------------------------------------------------------------------------------------
;                                                 CreateBD4()
;-----------------------------------------------------------------------------------------------------
Function CreateBD4.TBD4Rand()

	b.TBD4Rand = New TBD4Rand
	b\add = $0000B
	
	Return b
	
End Function

;-----------------------------------------------------------------------------------------------------
;                                                   BD4Rand()
;-----------------------------------------------------------------------------------------------------
Function BD4Rand(b.TBD4Rand, s)

	Return SRand48(b, s)

End Function

;-----------------------------------------------------------------------------------------------------
;													SRand48()
;-----------------------------------------------------------------------------------------------------
Function SRand48(b.TBD4Rand, a$ = "NoP")

	If a$ = "NoP" Then
		Return SRand48_2(b, MilliSecs() )
	Else
		Return SRand48_2(b, set_seed)
	End If
	
End Function

;-----------------------------------------------------------------------------------------------------
; 												    SRand48_2()
;-----------------------------------------------------------------------------------------------------
Function SRand48_2(b.TBD4Rand, set_seed )

	Local tmp = $0005DE

	b\mult = (tmp Shl 24) + $ECE66D
	b\seed = (set_seed Shl 16) + $330E		


End Function

;-----------------------------------------------------------------------------------------------------
;                                                   nextDouble
;-----------------------------------------------------------------------------------------------------
Function nextDouble#(b.TBD4Rand)

	Local accu, t1, t0

	accu = (b\mult And $FFFF) * (b\seed And $FFFF) + add;

	t0 = (accu And $FFFF)
	accu = accu Shr 16;

	accu = accu + (b\mult And $FFFF) * ((b\seed Shr 16) And $FFFF) 
	accu = accu + ((b\mult Shr 16) And $FFFF)*(b\seed And $FFFF)
					
	t1 = (accu And $FFFF);

	accu = accu Shr 16;
	accu = accu + (b\mult And $FFFF) * ((b\seed Shr 32) And $FFFF)
	accu = accu + ((b\mult Shr 16) And $FFFF) * ((b\seed Shr 16) And $FFFF)
	accu = accu + ((b\mult Shr 32) And $FFFF) * (b\seed And $FFFF)

	b\seed = ((accu And $FFFF) Shl 32) + (t1 Shl 16) + t0

	Return b\seed * 0.0000000000000035527136788005009293556213378906
	;java.lang.Math.pow(2,-48) = 2^-48 = ?

End Function


That float look way too long for B3D to handle.

The fact that nextDouble() is returning a single precision value in Blitz should tell you this is not going to work.

Are you sure that C conversion is accurate? Like Big10P I understood that longs in java are 64bit, whereas ( and I know my C is very rusty ) I thought C longs were 32 bit.
Yeah, I don't actually know java but assumed long ints must be 64bit since the code is performing a 32bit shift on the value, at one point. Doing so would make no sense if the value itself was only 32bit.

Hmm, that sounds logical .. I just converted the code, but I didn't try to understand what it does other than that it should generate random numbers somehow. When trying it, it returned *something*, so I thought that it would be allright. (Although I did notice that the generated numbers seem quite small for random values) So erm .. nevermind than.

Although I did notice that the generated numbers seem quite small for random values
In many languages, random numbers are between 0 and 1, if you want a random number between 147 and 501, you multiply the random number by 354 and add 147.