Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C++: 8, 16, 32, 64 -bittinen random-olio

jone2712 [15.05.2025 13:13:28]

#

Olen tutkinut 45 vuotta random-funktioita. Välillä projekti on ollut pitkäänkin pöytälaatikossa odottamassa uutta inspiraatiota. Oheinen random-olio tukee 8, 16, 32, 64 bittisiä randomeita. Kun sitä on tutkinut erilaisilla tilastoanalyyseillä, niin olio lähentelee täydellisyyttä - vaikka itse sanonkin.

Pitkällinen random taival on nyt lopussa, enkä luultavasti enää palaa ongelman pariin. Valitan kommenttien vähyyttä, mutta olion lyhyet funktiot kommentoivat itse itsensä. Koodin lopussa on lyhyt ja yksinkertainen main, josta on helppo jatkaa ja päästä jyvälle.

/*********************/
/* *** Jouni Aro *** */
/* *** 14.5.2025 *** */
/*********************/

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

//#define BORLAND

#ifdef BORLAND
    #include <conio.h>
    typedef unsigned    char  uint8;
    typedef unsigned   short uint16;
    typedef unsigned     int uint32;
    typedef unsigned __int64 uint64;
#else
    #include <cstdint>
    typedef  uint8_t  uint8;
    typedef uint16_t uint16;
    typedef uint32_t uint32;
    typedef uint64_t uint64;
#endif

class random
{
    public:

    random(void);
    ~random(void);

    uint8   rnd8(void);
    uint16 rnd16(void);
    uint32 rnd32(void);
    uint64 rnd64(void);

    uint8   rnd8(uint8);
    uint16 rnd16(uint16);
    uint32 rnd32(uint32);
    uint64 rnd64(uint64);

    private:

    uint8   tmp8(void);
    uint16 tmp16(void);
    uint32 tmp32(void);
    uint64 tmp64(void);

    uint8   R8A,  R8B;
    uint16 R16A, R16B;
    uint32 R32A, R32B;
    uint64 R64A, R64B;

    uint32 index4;
    uint32 p1, p2;
    uint32 p3, p4;

    void inc(void);
    uint64 EX[1<<8];
    void conf(uint8*);

    uint8  *os8; uint16 *os16;
    uint32 *os32; uint64 *os64;

    void swap8(uint8&, uint8&);
    void swap16(uint16&, uint16&);
    void swap32(uint32&, uint32&);
    void swap64(uint64&, uint64&);
};

random::random(void)
{
    memset(this, 0, sizeof(random));
    uint8 *tmp=new uint8[256];
    os8 = (uint8*) tmp;

    for (int i=0; i<256; i++)
    tmp[i]=(uint8)i;

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

    os8 =(uint8*) EX;
    os16=(uint16*)EX;
    os32=(uint32*)EX;
    os64=(uint64*)EX;

    delete[] tmp;
}

random::~random(void)
{
}

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

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

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

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

/***********************************************
***********************************************/

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

void random::conf(uint8 *tmp)
{
    register int i=0x00;
    register uint8 x, y;
    for (; i<0x3E7; i++)
    {
        x=rnd8(), y=rnd8();
        swap8(tmp[x], tmp[y]);
    }
}

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

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

    inc();
    return uint8(R8A^R8B);
}

inline uint16 random::tmp16(void)
{
    R16A+=uint16((os16[p1]>>8)^(os16[p2]<<8));
    R16B-=uint16((os16[p1]<<8)^(os16[p2]>>8));

    R16A-=os16[p3];
    R16B+=os16[p4];

    inc();
    return uint16(R16A^R16B);
}

inline uint32 random::tmp32(void)
{
    R32A+=(os32[p1]>>16)^(os32[p2]<<16);
    R32B-=(os32[p1]<<16)^(os32[p2]>>16);

    R32A-=os32[p3];
    R32B+=os32[p4];

    inc();
    return R32A^R32B;
}

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

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

    inc();
    return R64A^R64B;
}

/***********************************************
Seuraavat funktiot palauttavat modulo max:in.
***********************************************/

inline uint8 random::rnd8(uint8 max)
{
    register uint8 x=tmp8();
    register uint8 y=tmp8();
    swap8(os8[x], os8[y]);
    return uint8(tmp8()%max);
}

inline uint16 random::rnd16(uint16 max)
{
    register uint8 x=tmp8();
    register uint8 y=tmp8();
    swap16(os16[x], os16[y]);
    return uint16(tmp16()%max);
}

inline uint32 random::rnd32(uint32 max)
{
    register uint8 x=uint8(tmp32());
    register uint8 y=uint8(tmp32());
    swap32(os32[x], os32[y]);
    return tmp32()%max;
}

inline uint64 random::rnd64(uint64 max)
{
    register uint8 x=uint8(tmp64());
    register uint8 y=uint8(tmp64());
    swap64(os64[x], os64[y]);
    return tmp64()%max;
}

/***********************************************
Neljä seuraavaa funktiota palauttavat kukin
random-arvon, joissa käytössä on koko lukualue.
***********************************************/

inline uint8 random::rnd8(void)
{
    register uint8 x=tmp8();
    register uint8 y=tmp8();
    swap8(os8[x], os8[y]);
    return tmp8();
}

inline uint16 random::rnd16(void)
{
    register uint8 x=tmp8();
    register uint8 y=tmp8();
    swap16(os16[x], os16[y]);
    return uint16(tmp16());
}

inline uint32 random::rnd32(void)
{
    register uint8 x=uint8(tmp32());
    register uint8 y=uint8(tmp32());
    swap32(os32[x], os32[y]);
    return tmp32();
}

inline uint64 random::rnd64(void)
{
    register uint8 x=uint8(tmp64());
    register uint8 y=uint8(tmp64());
    swap64(os64[x], os64[y]);
    return tmp64();
}

/***********************************************
***********************************************/

int main(void)
{
    random F;
    uint8  a;
    uint16 b;
    uint32 c;
    uint64 d;

    for (int i=0; i<10; i++)
    {
        a = F.rnd8();
        b = F.rnd16();
        c = F.rnd32();
        d = F.rnd64();

        uint32 *x=(uint32*)&d;

        printf("%x ... ", (uint32)a);
        printf("%x ... ", (uint32)b);
        printf("%x ... ", (uint32)c);
        printf("%x%x \n", x[1],x[0]);
    }

    #ifdef BORLAND
        getch();
    #endif

    return 0;
}

Vastaus

Muista lukea kirjoitusohjeet.
Tietoa sivustosta