Re: nrand48 source code looks weird ?

From: Skybuck Flying (nospam_at_hotmail.com)
Date: 07/07/04

  • Next message: Michael Mair: "Re: Storing the size of an array in the structure itself"
    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 ;)


  • Next message: Michael Mair: "Re: Storing the size of an array in the structure itself"

    Relevant Pages

    • Compiling tcl 8.5.8 windows x64 Visual Studio 2008
      ... to 'int', possible loss of data ... int64' to 'int', possible loss of data ...
      (comp.lang.tcl)
    • Re: Question
      ... Warning test.c: 3 Assignment of int to unsigned short. ... Possible loss of precision ...
      (comp.lang.c)
    • Re: Question
      ... Warning test.c: 3 Assignment of int to unsigned short. ... Possible loss of precision ...
      (comp.lang.c)
    • Re: compiling Tcl 8.4 for 64bit on Windows XP64
      ... 'size_t' to 'unsigned int', possible loss of data ...
      (comp.lang.tcl)
    • Re: Weird conversion warning
      ... Which possible loss of data the compiler is seeing here? ... The result of adding two shorts is of type int. ... Whether this should cause a warning on ... To make the narrowing conversion explicit, ...
      (microsoft.public.vc.language)