Kirjautuminen

Haku

Tehtävät

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

jone2712 [13.05.2025 21:51:34]

#

Bugi löytyi ja korjattu.

/********************
* *** Jouni Aro *** *
* *** 13.5.2025 *** *
********************/

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

typedef uint8_t uint8;
typedef uint64_t uint64;

class random
{
    public:

    random(void);
    ~random(void);

    uint64 rnd64(uint64);
    uint64 rnd64cx(void);
    unsigned rnd8cx(void);
    unsigned rnd8(unsigned);

    private:

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

    void swap8(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

    uint8 *ex=(uint8*)EX;
    for (int i=0; i<2048; i++)
    {
        for (int i=0x00; i<999; i++)
        rnd8cx(); // sekoitetaan
        ex[i]=(uint8)rnd8cx();
    }
}

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::swap8(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;
    swap8(avain[x], avain[y]);
    return (tmp8()&0xff)%max;
}

inline unsigned random::rnd8cx(void)
{
    register unsigned x=tmp8()&0xff;
    register unsigned y=tmp8()&0xff;
    swap8(avain[x], avain[y]);
    return tmp8()&0xff;
}

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;
}

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

int main(void)
{
    random F;

    for (int i=0; i<10000; i++)
    {
        uint64 x=F.rnd64cx();
        /* tulostetaan x:n bitit ja hexsa-arvo */
        for (int i=63; i>=0; i--)
        {
            uint64 bit=x&(uint64)1<<i? 1: 0;
            printf("%u", (unsigned)bit);
        }
        printf("    ");
        unsigned *y=(unsigned*)&x;
        printf("%x %x\n", y[1], y[0]);
    }
    return 0;
}

Vastaus

Muista lukea kirjoitusohjeet.
Tietoa sivustosta