nrand48 source code looks weird ?

S

Skybuck Flying

This is the source code for nrand48 from gnuwin32 libgw32c

long int nrand48 (xsubi) unsigned short int xsubi[3];
{
long int result;

(void) __nrand48_r (xsubi, &__libc_drand48_data, &result);

return result;
}

// long int nrand48 (xsubi) unsigned short int xsubi[3];

What does the 'unsigned short int xsubi[3];' part mean after '(xsubi)' ?

The prototype in stdlib.h from the binaries is: (for some reason stdlib.h
was not in source distribution ?)

extern long int nrand48 (unsigned short int __xsubi[3]) __THROW;

So at first sight I would guess it has to do with throwing exceptions... but
now that I look at it again it I think it's the type for xsubi.

The original looks really weird:

1. long int nrand48 (xsubi) unsigned short int xsubi[3];

Isn't that supposed to look like this:

2. long int nrand48 (unsigned short int xsubi[3] );

Why did they write it as 1. ?

Is that just their preferred way of writing it down... or does it have some
sort of functionality ?

The prototype then again looks like 2. !? huh ?! :)

Euhm... Could this be a case of wacky c programmers ? eh.

Bye,
Skybuck.
 
J

Jens.Toerring

Skybuck Flying said:
This is the source code for nrand48 from gnuwin32 libgw32c
long int nrand48 (xsubi) unsigned short int xsubi[3];
{
long int result;
(void) __nrand48_r (xsubi, &__libc_drand48_data, &result);
return result;
}
// long int nrand48 (xsubi) unsigned short int xsubi[3];
What does the 'unsigned short int xsubi[3];' part mean after '(xsubi)' ?

That's the very old way function definitions where written back in
the K&R days when there wasn't a C standard. It's basically equiva-
lent to

long int nrand48( unsigned short int xsubi[ 3 ] )

In code dating back from that time you typically had function definitions
starting with

my_func( a, b, c )
int a,
char *b,
unsigned short c
{

which nowadays would be written as

int my_func( int a, char *b, unsigned short c )
{
The prototype in stdlib.h from the binaries is: (for some reason stdlib.h
was not in source distribution ?)
extern long int nrand48 (unsigned short int __xsubi[3]) __THROW;
So at first sight I would guess it has to do with throwing exceptions... but
now that I look at it again it I think it's the type for xsubi.

Better don't look at the header files unless you have very good reasons
to (or just out of curiosity). Lots of system-dependend magic is going
on there.
Regards, Jens
 
S

Skybuck Flying

Skybuck Flying said:
This is the source code for nrand48 from gnuwin32 libgw32c
long int nrand48 (xsubi) unsigned short int xsubi[3];
{
long int result;
(void) __nrand48_r (xsubi, &__libc_drand48_data, &result);
return result;
}
// long int nrand48 (xsubi) unsigned short int xsubi[3];
What does the 'unsigned short int xsubi[3];' part mean after '(xsubi)' ?

That's the very old way function definitions where written back in
the K&R days when there wasn't a C standard. It's basically equiva-
lent to

long int nrand48( unsigned short int xsubi[ 3 ] )

In code dating back from that time you typically had function definitions
starting with

my_func( a, b, c )
int a,
char *b,
unsigned short c
{

which nowadays would be written as

int my_func( int a, char *b, unsigned short c )
{

Yes, I was starting to think that C was a really #^#@$ language :)

Visual C/C++ 6.0 doesn't the support the old way...

<<<--- sigh --->>>

So now I have to re-write it all...

Fortunately for me... It's only a little bit of code... and fortunately I
rarely program in C :p =D

Thx for the description... Lol... it must be painfull to code in C :D

Bye,
Skybuck.
 
R

Richard Bos

Visual C/C++ 6.0 doesn't the support the old way...

Then it's not a C compiler. Are you sure you're not pretending to
compile C++?
Thx for the description... Lol... it must be painfull to code in C :D

Certainly not. It's a lot less painful if you actually learn to program.

Richard
 
S

Skybuck Flying

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 ;)
 
R

Richard Bos

Skybuck Flying said:
typedef unsigned __int16 uint16;

[ Snip loads of code including lots of non-standard types and
identifiers in the implementation's namespace. ]
So these warnings can probably be safely surpressed >D by using:

xsubi[0] = uint16( result & 0xffff );

uint16 is a type, not a function. Are you _very_ sure you're not
compiling C++?

Richard
 
G

Goran Larsson

In code dating back from that time you typically had function definitions
starting with

my_func( a, b, c )
int a,
char *b,
unsigned short c
{

No. We had function staring like this:

my_func( a, b, c )
int a;
char *b;
unsigned short c;
{
 
S

Skybuck Flying

Richard Bos said:
Skybuck Flying said:
typedef unsigned __int16 uint16;

[ Snip loads of code including lots of non-standard types and
identifiers in the implementation's namespace. ]
So these warnings can probably be safely surpressed >D by using:

xsubi[0] = uint16( result & 0xffff );

uint16 is a type, not a function. Are you _very_ sure you're not
compiling C++?

Hmm when splitting it up into multiple files it indeed produced an error

I think the correct typecast code to use is:

Not:

xsubi[0] = uint16( result & 0xffff );

Butttt:

xsubi[0] = (uint16) ( result & 0xffff );

:DD

Skybuck.
 
H

Harti Brandt

On Thu, 8 Jul 2004, Orhan Kavrakoglu wrote:

OK>On Wed, 7 Jul 2004 15:15:44 +0200, "Skybuck Flying"
OK>
OK>>
OK>>OK>
OK>>Thx for the description... Lol... it must be painfull to code in C :D
OK>>
OK>
OK>We're all sadists in this manner :)

And he probably hasn't see Intercal yet.

harti
 
K

Kenneth Brody

Skybuck Flying wrote:
[... old-vs-new function definitions ...]
Visual C/C++ 6.0 doesn't the support the old way...

<<<--- sigh --->>>

So now I have to re-write it all...
[...]

Excuse me? I have a program with several hundred thousand line of code
and 99.9% of the functions are coded "the old way". (We support platforms
that still don't allow "the new way".) It compiles just fine under VC6.0.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,190
Latest member
ClayE7480

Latest Threads

Top