Re: nrand48 source code looks weird ?
From: Skybuck Flying (nospam_at_hotmail.com)
Date: 07/07/04
- Previous message: Richard Bos: "Re: long follow by long is illegal"
- In reply to: Jens.Toerring_at_physik.fu-berlin.de: "Re: nrand48 source code looks weird ?"
- Next in thread: Richard Bos: "Re: nrand48 source code looks weird ?"
- Reply: Richard Bos: "Re: nrand48 source code looks weird ?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Wed, 7 Jul 2004 15:31:50 +0200
Finally...
A working nrand48() :)
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
//typedef unsigned long long uint64_t
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
{
unsigned short int __x[3]; /* Current state. */
unsigned short int __old_x[3]; /* Old state. */
unsigned short int __c; /* Additive const. in congruential formula. */
unsigned short int __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 ( unsigned short int xsubi[3], struct drand48_data
*buffer )
{
uint64 X;
uint64 result;
/* Initialize buffer, if not yet done. */
// built in bullshit removed
// if (__builtin_expect (!buffer->__init, 0))
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. */
X = (uint64) xsubi[2] << 32 | (uint32) xsubi[1] << 16 | xsubi[0];
result = X * buffer->__a + buffer->__c;
xsubi[0] = result & 0xffff;
xsubi[1] = (result >> 16) & 0xffff;
xsubi[2] = (result >> 32) & 0xffff;
return 0;
}
int __nrand48_r (
unsigned short int xsubi[3],
struct drand48_data *buffer,
long int *result )
{
/* Compute next state. */
if (__drand48_iterate (xsubi, buffer) < 0)
{
return -1;
}
/* Store the result. */
if (sizeof (unsigned short int) == 2)
{
*result = xsubi[2] << 15 | xsubi[1] >> 1;
}
else
{
*result = xsubi[2] >> 1;
}
return 0;
}
long int nrand48 (unsigned short int xsubi[3])
{
long int result;
(void) __nrand48_r (xsubi, &__libc_drand48_data, &result);
return result;
}
int main()
{
unsigned short state48[3];
printf("%d \n", nrand48(state48) );
return 0;
}
Compiling...
Main.cpp
C:\C TESTEN\TestNRand48\Main.cpp(59) : warning C4244: '=' : conversion from
'unsigned __int64' to 'unsigned short', possible loss of data
C:\C TESTEN\TestNRand48\Main.cpp(60) : warning C4244: '=' : conversion from
'unsigned __int64' to 'unsigned short', possible loss of data
C:\C TESTEN\TestNRand48\Main.cpp(61) : warning C4244: '=' : conversion from
'unsigned __int64' to 'unsigned short', possible loss of data
Linking...
TestNRand48.exe - 0 error(s), 3 warning(s)
Except these three lines produce a warning in visual c 6
xsubi[0] = result & 0xffff;
xsubi[1] = (result >> 16) & 0xffff;
xsubi[2] = (result >> 32) & 0xffff;
Seeing the 0xffff I can conclude that unsigned short must be a unsigned 16
bit integer.
So these warnings can probably be safely surpressed >D by using:
xsubi[0] = uint16( result & 0xffff );
xsubi[1] = uint16( (result >> 16) & 0xffff );
xsubi[2] = uint16( (result >> 32) & 0xffff );
Jip..
That did the trick.
Bye,
Skybuck
P.S.: Take care ;)
- Previous message: Richard Bos: "Re: long follow by long is illegal"
- In reply to: Jens.Toerring_at_physik.fu-berlin.de: "Re: nrand48 source code looks weird ?"
- Next in thread: Richard Bos: "Re: nrand48 source code looks weird ?"
- Reply: Richard Bos: "Re: nrand48 source code looks weird ?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|