Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C++: vielä 64-bittinen random-olio

jone2712 [10.05.2025 01:57:19]

#

Tuli niin vähällä lisätyöllä 64-bittinen random-olio, niin toteutin sen. Koodin pitäisi kommentoida itse itsensä.

/********************
* *** Jouni Aro *** *
* *** 10.5.2025 *** *
********************/

#include <stdio.h>
#include <memory.h>

typedef unsigned char uint8;
typedef unsigned __int64 uint64;

class random
{
    public:

    random(void);
    ~random(void);

    uint64 rnd64(uint64);
    unsigned rnd8(unsigned);

    private:

    void index4(void);
    uint64 tmp64(void);
    unsigned tmp8(void);

    void swap(uint8&, uint8&);
    void swap64(uint64&, uint64&);

    unsigned xxcx;
    uint8 R8A, R8B;
    uint64 EX[1<<8];
    uint8 avain[256];
    uint64 R64A, R64B;
    int p1, p2, p3, p4;
};

random::random(void)
{
    memset(this, 0, sizeof(random));
    xxcx=1+(2<<8)+(3<<16)+(4<<24);
    p1=1; p2=2; p3=3; p4=4;
    R64A=10101; R64B=20202;
    R8A=101; R8B=202;

    for (int i=0; i<256; i++)
    avain[i]=(uint8)i; // ext

    for (int i=0; i<999; i++)
    rnd8(128); // sekoitetaan

    uint8 *ex=(uint8*)EX;
    for (int i=0; i<2048; i++)
    ex[i]=(uint8)rnd8(256);
}

random::~random(void)
{
}

inline void random::index4(void)
{
    ++xxcx; p1=xxcx&255;
    p2=(xxcx>>0x08)&255;
    p3=(xxcx>>16)&255;
    p4=(xxcx>>24)&255;
}

inline uint64 random::tmp64(void)
{
    R64A+=(EX[p1]>>32)^(EX[p2]<<32);
    R64B-=(EX[p1]<<32)^(EX[p2]>>32);

    R64A-=EX[p3];
    R64B+=EX[p4];

    index4();
    return R64A^R64B;
}

inline unsigned random::tmp8(void)
{
    R8A+=(uint8)((avain[p1]>>4)^(avain[p2]<<4));
    R8B-=(uint8)((avain[p1]<<4)^(avain[p2]>>4));

    R8A-=avain[p3];
    R8B+=avain[p4];

    index4();
    return R8A^R8B;
}

inline void random::swap(uint8 &x, uint8 &y)
{
    register uint8 z=x; x=y; y=z;
}

inline void random::swap64(uint64 &x, uint64 &y)
{
    register uint64 z=x; x=y; y=z;
}

inline unsigned random::rnd8(unsigned max)
{
    register unsigned x=tmp8()&0xff;
    register unsigned y=tmp8()&0xff;
    swap(avain[x], avain[y]);
    return (tmp8()&0xff)%max;
}

inline uint64 random::rnd64(uint64 max)
{
    register unsigned x=(unsigned)tmp64()&0xff;
    register unsigned y=(unsigned)tmp64()&0xff;
    swap64(EX[x], EX[y]);
    return tmp64()%max;
}

int main(void)
{
    random F;

    for (int i=0; i<10; i++)
    {
        uint64 x=F.rnd64((uint64)0xffffffffffffffff);
        /* *** tulostetaan x:n bitit *** */
        for (int i=63; i>=0; i--)
        printf("%u", x&(1<<i)? 1: 0);
        printf("\n");
    }
    return 1;
}

Vastaus

Muista lukea kirjoitusohjeet.
Tietoa sivustosta