S
Skybuck Flying
Hi,
This is a somewhat cleaned up version 0.02 of the nrand48() routine.
There are still a few issues:
This code needs brackets but where ?
X = (uint64) xsubi[2] << 32 | (uint32) xsubi[1] << 16 | xsubi[0];
This code also needs brackets but where ?
*result = xsubi[2] << 15 | xsubi[1] >> 1;
Since operator precedence is different in other languages etc... so this
code needs brackets to be able to port/convert/translate it to any other
language, to prevent errors/bugs and for clearity sakes
The last thing to check is the output.
Can somebody on a unix system... run this program... preferablly *without*
all the extra code... and use the original nrand48() function... and then
compare the unix output with this windows xp output to see if it's exactly
the same ? That would be great =D
#include <stdlib.h>
#include <stdio.h>
typedef signed __int8 sint8;
typedef unsigned __int8 uint8;
typedef signed __int16 sint16;
typedef unsigned __int16 uint16;
typedef signed __int32 sint32;
typedef unsigned __int32 uint32;
typedef signed __int64 sint64;
typedef unsigned __int64 uint64;
/* Data structure for communication with thread safe versions. This
type is to be regarded as opaque. It's only exported because users
have to allocate objects of this type. */
struct drand48_data
{
uint16 __x[3]; /* Current state. */
uint16 __old_x[3]; /* Old state. */
uint16 __c; /* Additive const. in congruential formula. */
uint16 __init; /* Flag for initializing. */
uint64 __a; /* Factor in congruential formula. */
};
/* Global state for non-reentrant functions. */
struct drand48_data __libc_drand48_data;
int __drand48_iterate ( uint16 xsubi[3], struct drand48_data *buffer )
{
uint64 X;
uint64 result;
/* Initialize buffer, if not yet done. */
if (buffer->__init == 0)
{
buffer->__a = 0x5deece66du;
buffer->__c = 0xb;
buffer->__init = 1;
}
/* Do the real work. We choose a data type which contains at least
48 bits. Because we compute the modulus it does not care how
many bits really are computed. */
// this code needs brackets ! ( ( ) ) etc but where ?
X = (uint64) xsubi[2] << 32 | (uint32) xsubi[1] << 16 | xsubi[0];
result = X * buffer->__a + buffer->__c;
// use typecast to surpress warnings
xsubi[0] = uint16( result & 0xffff );
xsubi[1] = uint16( (result >> 16) & 0xffff );
xsubi[2] = uint16( (result >> 32) & 0xffff );
return 0;
}
sint32 __nrand48_r ( uint16 xsubi[3], struct drand48_data *buffer, sint32
*result )
{
/* Compute next state. */
if (__drand48_iterate (xsubi, buffer) < 0)
{
return -1;
}
/* Store the result. */
if (sizeof (unsigned short int) == 2)
{
// this code needs brackets ! ( ( ) ) etc but where ?
*result = xsubi[2] << 15 | xsubi[1] >> 1;
}
else
{
*result = xsubi[2] >> 1;
}
return 0;
}
sint32 nrand48 (uint16 xsubi[3])
{
sint32 result;
(void) __nrand48_r (xsubi, &__libc_drand48_data, &result);
return result;
}
int main()
{
uint16 state48[3];
printf("%d \n", nrand48(state48) );
printf("%d \n", nrand48(state48) );
printf("%d \n", nrand48(state48) );
printf("%d \n", nrand48(state48) );
printf("%d \n", nrand48(state48) );
// the output is:
// 1288336289
// 893806678
// 810173679
// 37620279
// 474250687
return 0;
}
Bye,
Skybuck.
This is a somewhat cleaned up version 0.02 of the nrand48() routine.
There are still a few issues:
This code needs brackets but where ?
X = (uint64) xsubi[2] << 32 | (uint32) xsubi[1] << 16 | xsubi[0];
This code also needs brackets but where ?
*result = xsubi[2] << 15 | xsubi[1] >> 1;
Since operator precedence is different in other languages etc... so this
code needs brackets to be able to port/convert/translate it to any other
language, to prevent errors/bugs and for clearity sakes
The last thing to check is the output.
Can somebody on a unix system... run this program... preferablly *without*
all the extra code... and use the original nrand48() function... and then
compare the unix output with this windows xp output to see if it's exactly
the same ? That would be great =D
#include <stdlib.h>
#include <stdio.h>
typedef signed __int8 sint8;
typedef unsigned __int8 uint8;
typedef signed __int16 sint16;
typedef unsigned __int16 uint16;
typedef signed __int32 sint32;
typedef unsigned __int32 uint32;
typedef signed __int64 sint64;
typedef unsigned __int64 uint64;
/* Data structure for communication with thread safe versions. This
type is to be regarded as opaque. It's only exported because users
have to allocate objects of this type. */
struct drand48_data
{
uint16 __x[3]; /* Current state. */
uint16 __old_x[3]; /* Old state. */
uint16 __c; /* Additive const. in congruential formula. */
uint16 __init; /* Flag for initializing. */
uint64 __a; /* Factor in congruential formula. */
};
/* Global state for non-reentrant functions. */
struct drand48_data __libc_drand48_data;
int __drand48_iterate ( uint16 xsubi[3], struct drand48_data *buffer )
{
uint64 X;
uint64 result;
/* Initialize buffer, if not yet done. */
if (buffer->__init == 0)
{
buffer->__a = 0x5deece66du;
buffer->__c = 0xb;
buffer->__init = 1;
}
/* Do the real work. We choose a data type which contains at least
48 bits. Because we compute the modulus it does not care how
many bits really are computed. */
// this code needs brackets ! ( ( ) ) etc but where ?
X = (uint64) xsubi[2] << 32 | (uint32) xsubi[1] << 16 | xsubi[0];
result = X * buffer->__a + buffer->__c;
// use typecast to surpress warnings
xsubi[0] = uint16( result & 0xffff );
xsubi[1] = uint16( (result >> 16) & 0xffff );
xsubi[2] = uint16( (result >> 32) & 0xffff );
return 0;
}
sint32 __nrand48_r ( uint16 xsubi[3], struct drand48_data *buffer, sint32
*result )
{
/* Compute next state. */
if (__drand48_iterate (xsubi, buffer) < 0)
{
return -1;
}
/* Store the result. */
if (sizeof (unsigned short int) == 2)
{
// this code needs brackets ! ( ( ) ) etc but where ?
*result = xsubi[2] << 15 | xsubi[1] >> 1;
}
else
{
*result = xsubi[2] >> 1;
}
return 0;
}
sint32 nrand48 (uint16 xsubi[3])
{
sint32 result;
(void) __nrand48_r (xsubi, &__libc_drand48_data, &result);
return result;
}
int main()
{
uint16 state48[3];
printf("%d \n", nrand48(state48) );
printf("%d \n", nrand48(state48) );
printf("%d \n", nrand48(state48) );
printf("%d \n", nrand48(state48) );
printf("%d \n", nrand48(state48) );
// the output is:
// 1288336289
// 893806678
// 810173679
// 37620279
// 474250687
return 0;
}
Bye,
Skybuck.