#1
  1. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,995
    Rep Power
    481

    Type-punned pointer


    (I suppose the answer is "Use a gsl prng. You already use gsl in the rest of your code.")

    What is a type-punned pointer ?

    What is an aliasing rule?

    Thanks.

    compiled with
    g++ -Wall
    I get many warnings
    warning: dereferencing type-punned pointer will break strict-aliasing rules
    A few of them are marked below.
    kptr is a long int and *&klotz0_

    I haven't figured out how to reproduce the warning in a small way---this code fragment doesn't cause the warning.

    space for float*random_num is allocated before used.
    #define NPTS 1000005 // ! # of data points

    Someone converted the code from FORTRAN to c++.

    When I generate a million numbers with random_number, sort and plot the data forms an evenly distributed line from 0 to 1 versus index number.
    Code:
    //#define EXTERN extern
    
    /* Common Block Declarations */
    struct klotz0_1_ {
        FLOAT buff[607];
        long int ptr;
    };
    
    #define klotz0_1 (*(struct klotz0_1_ *) &klotz0_)
    #define min(a,b) (a<b)?a:b
    
    struct klotz1_1_ {
        FLOAT xbuff[1024];
        long int first, xptr;
    };
    
    //#define klotz1_1 (*(struct klotz1_1_ *) &klotz1_)
    
    /* Initialized data */
    struct KLOTZ {
        long int fill_1[1214];
        long int e_2;
        } klotz0_ = { {0}, 0 };
    
    //struct {
    //    FLOAT fill_1[1024];
    //    long int e_2[2];
    //    FLOAT e_3;
    //    } klotz1_ = { {0}, 0, 0, 0. };
    
    
    
    
    int zufall_(long int n, FLOAT *a)
    //long int n;
    //FLOAT *a;
    {
        long int buffsz = 607;
    
        long int left, aptr, bptr, aptr0, i, k, q;
        FLOAT t;
        long int nn, vl, qq, k273, k607, kptr;
    
    
    /* portable lagged Fibonacci series uniform random number */
    /* generator with "lags" -273 und -607: */
    /* W.P. Petersen, IPS, ETH Zuerich, 19 Mar. 92 */
    
    
        aptr = 0;
        nn = n;
    
    L1:
    
        if (nn <= 0) {
    	return 0;
        }
    
    /* factor nn = q*607 + r */
    
        q = (nn - 1) / 607;
        left = buffsz - klotz0_1.ptr;
                        //random_number_v1.cpp:63:21: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
    
        if (q <= 1) {
    
    /* only one or fewer full segments */
    
    	if (nn < left) {
                kptr = klotz0_1.ptr;
                       //random_number_v1.cpp:70:20: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
    	    for (i = 0; i < nn; ++i) {
    		a[i + aptr] = klotz0_1.buff[kptr + i];
    	        //random_number_v1.cpp:72:17: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
    	    }
    	    klotz0_1.ptr += nn;
    	    return 0;
    	} else {
                kptr = klotz0_1.ptr;
    /*pragma _CRI ivdep*/
    	    for (i = 0; i < left; ++i) {
    		a[i + aptr] = klotz0_1.buff[kptr + i];
    	    }
    	    klotz0_1.ptr = 0;
    	    aptr += left;
    	    nn -= left;
    /*  buff -> buff case */
    	    vl = 273;
    	    k273 = 334;
    	    k607 = 0;
    	    for (k = 0; k < 3; ++k) {
    /*pragma _CRI ivdep*/
    		for (i = 0; i < vl; ++i) {
    		   t = klotz0_1.buff[k273+i]+klotz0_1.buff[k607+i];
    		   klotz0_1.buff[k607+i] = t - (FLOAT) ((long int) t);
    		}
    		k607 += vl;
    		k273 += vl;
    		vl = 167;
    		if (k == 0) {
    		    k273 = 0;
    		}
    	    }
    	    goto L1;
    	}
        } else {
    
    /* more than 1 full segment */
    
            kptr = klotz0_1.ptr;
    /*pragma _CRI ivdep*/
    	for (i = 0; i < left; ++i) {
    	    a[i + aptr] = klotz0_1.buff[kptr + i];
    	}
    	nn -= left;
    	klotz0_1.ptr = 0;
    	aptr += left;
    
    /* buff -> a(aptr0) */
    
    	vl = 273;
    	k273 = 334;
    	k607 = 0;
    	for (k = 0; k < 3; ++k) {
    	    if (k == 0) {
    /*pragma _CRI ivdep*/
    		for (i = 0; i < vl; ++i) {
    		    t = klotz0_1.buff[k273+i]+klotz0_1.buff[k607+i];
    		    a[aptr + i] = t - (FLOAT) ((long int) t);
    		}
    		k273 = aptr;
    		k607 += vl;
    		aptr += vl;
    		vl = 167;
    	    } else {
    /*pragma _CRI ivdep*/
    		for (i = 0; i < vl; ++i) {
    		    t = a[k273 + i] + klotz0_1.buff[k607 + i];
    		    a[aptr + i] = t - (FLOAT) ((long int) t);
    		}
    		k607 += vl;
    		k273 += vl;
    		aptr += vl;
    	    }
    	}
    	nn += -607;
    
    /* a(aptr-607) -> a(aptr) for last of the q-1 segments */
    
    	aptr0 = aptr - 607;
    	vl = 607;
    
    	for (qq = 0; qq < q-2; ++qq) {
    	    k273 = aptr0 + 334;
    /*pragma _CRI ivdep*/
    	    for (i = 0; i < vl; ++i) {
    		t = a[k273 + i] + a[aptr0 + i];
    		a[aptr + i] = t - (FLOAT) ((long int) t);
    	    }
    	    nn += -607;
    	    aptr += vl;
    	    aptr0 += vl;
    	}
    
    /* a(aptr0) -> buff, last segment before residual */
    
    	vl = 273;
    	k273 = aptr0 + 334;
    	k607 = aptr0;
    	bptr = 0;
    	for (k = 0; k < 3; ++k) {
    	    if (k == 0) {
    /*pragma _CRI ivdep*/
    		for (i = 0; i < vl; ++i) {
    		    t = a[k273 + i] + a[k607 + i];
    		    klotz0_1.buff[bptr + i] = t - (FLOAT) ((long int) t);
    		}
    		k273 = 0;
    		k607 += vl;
    		bptr += vl;
    		vl = 167;
    	    } else {
    /*pragma _CRI ivdep*/
    		for (i = 0; i < vl; ++i) {
    		    t = klotz0_1.buff[k273 + i] + a[k607 + i];
    		    klotz0_1.buff[bptr + i] = t - (FLOAT) ((long int) t);
    		}
    		k607 += vl;
    		k273 += vl;
    		bptr += vl;
    	    }
    	}
    	goto L1;
        }
    } /* zufall_ */
    
    
    long int zufalli_(long int  seed)
    //long int seed;
    {
        /* Initialized data */
    
        long int kl = 9373;
        long int ij = 1802;
    
        /* Local variables */
        long int i, j, k, l, m;
        FLOAT s, t;
        long int ii, jj;
    
    
    /*  generates initial seed buffer by linear congruential */
    /*  method. Taken from Marsaglia, FSU report FSU-SCRI-87-50 */
    /*  variable seed should be 0 < seed <31328 */
    
    
        if (seed != 0) {
    	ij = seed;
        }
    
        i = ij / 177 % 177 + 2;
        j = ij % 177 + 2;
        k = kl / 169 % 178 + 1;
        l = kl % 169;
        for (ii = 0; ii < 607; ++ii) {
    	s = 0.;
    	t = .5;
    	for (jj = 1; jj <= 24; ++jj) {
    	    m = i * j % 179 * k % 179;
    	    i = j;
    	    j = k;
    	    k = m;
    	    l = (l * 53 + 1) % 169;
    	    if (l * m % 64 >= 32) {
    		s += t;
    	    }
    	    t *= (FLOAT).5;
    	}
    	klotz0_1.buff[ii] = s;
        }
        return 0;
    } /* zufalli_ */
    
    
    long int zufallsv_(FLOAT *svblk)
    //FLOAT *svblk;
    {
        long int i;
    
    
    /*  saves common blocks klotz0, containing seeds and */
    /*  polong inter to position in seed block. IMPORTANT: svblk must be */
    /*  dimensioned at least 608 in driver. The entire contents */
    /*  of klotz0 (polong inter in buff, and buff) must be saved. */
    
    
        /* Function Body */
        svblk[0] = (FLOAT) klotz0_1.ptr;
    /*pragma _CRI ivdep*/
        for (i = 0; i < 607; ++i) {
    	svblk[i + 1] = klotz0_1.buff[i];
        }
    
        return 0;
    } /* zufallsv_ */
    
    long int zufallrs_(FLOAT *svblk)
    //FLOAT *svblk;
    {
        long int i;
    
    
    /*  restores common block klotz0, containing seeds and pointer */
    /*  to position in seed block. IMPORTANT: svblk must be */
    /*  dimensioned at least 608 in driver. The entire contents */
    /*  of klotz0 must be restored. */
    
    
        klotz0_1.ptr = (long int) svblk[0];
    /*pragma _CRI ivdep*/
        for (i = 0; i < 607; ++i) {
    	klotz0_1.buff[i] = svblk[i + 1];
        }
    
        return 0;
    } /* zufallrs_ */
    
    
    void random_number(long int seed)
    {
        /*long int tom;*/    
    //    extern long int fischet_(), zufalli_(), normalt_(), zufallt_();
    
        zufalli_(seed);
        zufall_(NPTS,random_num);
    
        /*for(tom=0;tom<100;tom++) prlong intf("random_number[%d]=%f\n",tom,random_num[tom]);*/
    }
    [code]Code tags[/code] are essential for python code and Makefiles!
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    First I ever heard of it. So I immediately went to Wikipedia. "Strong and weak typing" at http://en.wikipedia.org/wiki/Strong_and_weak_typing:

    Weak typing and coercion

    Aahz Maruch writes that "Coercion occurs when you have a statically-typed language and you use the syntactic features of the language to force the usage of one type as if it were a different type (consider the common use of void* in C). Coercion is usually a symptom of weak typing. Conversion, OTOH, creates a brand-new object of the appropriate type."

    GCC describes this as type-punning and warns that it will break strict aliasing. Thiago Macieira discusses several problems that can arise when type-punning causes the compiler to make inappropriate optimizations.
    That links you to their article, "Type punning" at http://en.wikipedia.org/wiki/Type_punning:
    In computer science, type punning is a common term for any programming technique that subverts or circumvents the type system of a programming language in order to achieve an effect that would be difficult or impossible to achieve within the bounds of the formal language.

    In C and C++, constructs such as type conversion, union, and reinterpret_cast are provided in order to permit many kinds of type punning, although some kinds are not actually supported by the standard language.
    The first article also links to their article, "Aliasing(computing)", at http://en.wikipedia.org/wiki/Aliasing_(computing), though by way of a detour to the article on graphics aliasing:
    In computing, aliasing describes a situation in which a data location in memory can be accessed through different symbolic names in the program. Thus, modifying the data through one name implicitly modifies the values associated to all aliased names, which may not be expected by the programmer. As a result, aliasing makes it particularly difficult to understand, analyze and optimize programs. Aliasing analysers intend to make and compute useful information for understanding aliasing in programs.
    That should help get you started.
  4. #3
  5. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,995
    Rep Power
    481
    Thank you!
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo