Skybuck Flying <nospam@hotmail.com> wrote:[color=blue]
> I am beginning to see why microsoft did not include this nrand SHIT !!!![/color]
MS probably never tried to because that functions have been declared
obsolete since years and years and years. From the way you sound they
probably were already declared deprecated before you were born. My
Linux documentation explicitely says
These functions are declared obsolete by SVID 3, which
states that rand(3) should be used instead.
You are the only one insisting on using it.
[color=blue]
> 1. The documentation is SHIT[/color]
Have you read it? It can't keep from getting the feeling that you didn't.
Have you already figured out how to use the "man" command under UNIX?
[color=blue]
> 2. The implementation is SHIT[/color]
No, it works exactly as it should. It's only you making a mess out
of it when you try to move it to another system without properly
understanding what's going on.
<more stupid rant snipped>
[color=blue]
> How is one supposed to use nrand48( ??? ) ?????????????[/color]
[color=blue]
> With some parameters ???[/color]
[color=blue]
> The documentation is not clear about this or the function is mal functioning
> ;)[/color]
Exactly as described in the documentation. You call it with an array
of 3 unsigned short int values which contain values for storing the
intermediate state of the function between calls.
[color=blue]
> I think the documentation says nrand48 can be used without initialising
> anything ???[/color]
No, you do that by setting initial values for the 3 values in the
array you call 'state48'.
[color=blue]
> int main()
> {
> uint16 state48[3];[/color]
[color=blue]
> //state48[0] = 0;
> //state48[1] = 0;
> //state48[2] = 0;[/color]
That way the state48 array is uninitialized, holding some completely
random values when you start the program. The values have even a
good chance to be different on each invocation of the program,
resulting in a different sequence of numbers in each run.
Make that
unsigned short int state48[ 3 ] = { 0, 0, 0 };
in order to start with a well-defined initial value.
[color=blue]
> 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) );[/color]
<bogus resultts snipped>
Guess what: I get (with state48 initialized with 0) on my Linux box::
0
2116118
89401895
379337186
782977366
196130996
and on IRIX, i.e. using a different architecture, a different OS,
a different compiler, a different libc:
0
2116118
89401895
379337186
782977366
196130996
and on OSF1, i.e. another different architecture, another different OS,
another different compiler and another different libc:
0
2116118
89401895
379337186
782977366
196130996
So you see: three different, independend implementations of the function
and all giving the same results. I'm sorry, but since I'm just a "STUPID
UNIX FUCKHEAD" I can't deliver any results for an MS system...
[color=blue]
> return 0;
> }[/color]
[color=blue]
> It would be nice if nrand48 and the test program produced the same results[/color]
Well, wouldn't it?
[color=blue]
> Isn't it supposed to produce the same output ?[/color]
[color=blue]
> If Yes,[/color]
[color=blue]
> Then possibly test program flawed
> Then possibly nrand48 routine flawed[/color]
Probably both.
[color=blue]
> I need a good nrand48() function to make sure the program works like it was
> designed.[/color]
The way you try to do it (i.e. by copying some rather cryptic internal
code from some implementation you don't seem to understand instead of
trying to understand the algorithm and doing a clean new implementation)
obviously makes everything unnecessarily complicated and results in
nearly unreadable code.
Look, the following took me less than 10 minutes to put together.
And it gives exactly the same results as using the nrand48() function
coming from the glibc when comparing results for the first ten million
calls (which of course is no proof that the implementation is correct
but seems to be good enough for me at the moment):
#include <stdio.h>
#include <stdlib.h>
static long int n48( unsigned short int xsub[ 3 ] );
int main( void )
{
int i;
unsigned short xsubi[ 3 ] = { 0, 0, 0 };
for ( i = 0; i < 5; i++ )
printf( "%ld\n", n48( xsubi ) );
return EXIT_SUCCESS;
}
static long int n48( unsigned short int xsub[ 3 ] )
{
static unsigned long long a = 0x5DEECE66DULL;
static unsigned long long c = 0xBULL;
unsigned long long X = ( ( unsigned long long ) xsub[ 2 ] << 32 ) |
( ( unsigned long long ) xsub[ 1 ] << 16 ) |
( unsigned long long ) xsub[ 0 ];
X = X * a + c;
xsub[ 0 ] = X & 0xFFFF;
xsub[ 1 ] = ( X >> 16 ) & 0xFFFF;
xsub[ 2 ] = ( X >> 32 ) & 0xFFFF;
return ( X >> 17 ) & 0x7FFFFFFFUL;
}
All you need to do is replace the "unsigned long long" stuff by uint64
(or whatever) because your compiler does not seem to know about "long
long" and you thus have to use some special magic to get at the correct
types. But don't blame this on C, it's just something our compiler re-
quires. You may also have to remove the "ULL" bit after the constants
or replace it with something your compiler understands.
[color=blue]
> Though seeing a coder not using ( ( ( ) ) ) to make the calculations more
> robust starts to make me wonder about the coder's quality level.[/color]
They don't make calculations anymore robust. If you put some where they
aren't required you may just make the code a bit easier to read for an
unexperienced programmer. Why don't you at least take the time to look up
a simple table of operator precendences in C and find out where they are
needed? Or don't you understand the code at all you're trying to write?
Regards, Jens
--
\ Jens Thoms Toerring ___
Jens.Toerring@physik.fu-berlin.de
\__________________________
http://www.toerring.de