Math-Random-MTwist
view release on metacpan or search on metacpan
return RETVAL;
}
static int loadstate(mt_state* state, SV* file_sv) {
PerlIO* pio = NULL;
FILE* fh = NULL;
int RETVAL = 0;
dTHX;
fh = open_file_from_sv(file_sv, "r", &pio);
if (fh) {
RETVAL = state ? mts_loadstate(fh, state) : mt_loadstate(fh);
if (pio)
PerlIO_releaseFILE(pio, fh);
else
fclose(fh);
}
return RETVAL;
}
static void set_state_from_sv(SV* sv_state, mt_state* state) {
STRLEN len;
dTHX;
if (!SvPOK(sv_state))
croak("State must be a string");
len = SvCUR(sv_state);
if (len != sizeof(mt_state))
croak("Need exactly %d state bytes, not %d", sizeof(mt_state), len);
*state = *(mt_state*)SvPV_nolen(sv_state);
if (state->stateptr < 0 || state->stateptr > MT_STATE_SIZE) {
warn("stateptr value %d outside valid range [0, %d], using 0 instead",
state->stateptr, MT_STATE_SIZE);
state->stateptr = 0;
}
}
MODULE = Math::Random::MTwist PACKAGE = Math::Random::MTwist
PROTOTYPES: ENABLE
mt_state*
new_state(char* CLASS)
CODE:
Newxz(RETVAL, 1, mt_state);
if (RETVAL == NULL)
croak("Could not allocate state memory");
OUTPUT:
RETVAL
void
DESTROY(mt_state* state)
PPCODE:
Safefree(state);
UV
seed32(mt_state* state, uint32_t seed)
CODE:
mts_seed32new(state, seed);
RETVAL = seed;
OUTPUT:
RETVAL
UV
_seed32(uint32_t seed)
CODE:
mt_seed32new(seed);
RETVAL = seed;
OUTPUT:
RETVAL
UV
srand(mt_state* state, uint32_t seed = 0)
CODE:
RETVAL = srand50c(state, items == 1 ? NULL : &seed);
OUTPUT:
RETVAL
UV
_srand(uint32_t seed = 0)
CODE:
RETVAL = srand50c(NULL, items == 0 ? NULL : &seed);
OUTPUT:
RETVAL
UV
timeseed(mt_state* state)
UV
_timeseed()
CODE:
RETVAL = timeseed(NULL);
OUTPUT:
RETVAL
UV
fastseed(mt_state* state)
UV
_fastseed()
CODE:
RETVAL = fastseed(NULL);
OUTPUT:
RETVAL
UV
goodseed(mt_state* state)
UV
_goodseed()
CODE:
RETVAL = goodseed(NULL);
OUTPUT:
RETVAL
void
bestseed(mt_state* state)
void
_bestseed()
PPCODE:
bestseed(NULL);
void
seedfull(mt_state* state, AV* seeds)
PPCODE:
seedfull(state, seeds);
void
_seedfull(AV* seeds)
PPCODE:
seedfull(NULL, seeds);
SV*
irand32(mt_state* state);
ALIAS:
irand64 = 1
irand = 2
CODE:
#if IVSIZE >= 8
if (ix)
RETVAL = newSVuv(mts_llrand(state));
#elif defined(UINT64_MAX)
if (ix)
RETVAL = svpv_uint64(mts_llrand(state));
#else
if (ix == 1)
XSRETURN_UNDEF;
#endif
else
RETVAL = newSVuv(state ? mts_lrand(state) : mt_lrand());
OUTPUT:
RETVAL
SV*
_irand32();
ALIAS:
_irand64 = 1
_irand = 2
CODE:
#if IVSIZE >= 8
if (ix)
RETVAL = newSVuv(mt_llrand());
#elif defined(UINT64_MAX)
if (ix)
RETVAL = svpv_uint64(mt_llrand());
#else
if (ix == 1)
XSRETURN_UNDEF;
#endif
else
RETVAL = newSVuv(mt_lrand());
OUTPUT:
RETVAL
SV*
irand128(mt_state* state);
CODE:
#if IVSIZE >= 16
RETVAL = newSVuv(mts_u128rand(state));
#elif MT_HAS_INT128
RETVAL = svpv_uint128(mts_u128rand(state));
#else
XSRETURN_UNDEF;
#endif
OUTPUT:
RETVAL
SV*
_irand128();
CODE:
RETVAL = mt_drand();
else
#if NVMANTBITS <= 64
RETVAL = mt_ldrand();
#else
RETVAL = mt_lldrand();
#endif
if (bound)
RETVAL *= bound;
OUTPUT:
RETVAL
### Interestingly, randstr() is faster than rd_double(2).
SV*
randstr(mt_state* state, STRLEN length = I2D_SIZE)
CODE:
RETVAL = randstr(state, length);
OUTPUT:
RETVAL
SV*
_randstr(STRLEN length = I2D_SIZE)
CODE:
RETVAL = randstr(NULL, length);
OUTPUT:
RETVAL
#define RETURN_I2D(have_index) { \
if (have_index) { \
switch(index) { \
case 0: \
XSRETURN_NV(i2d.dbl); \
case 1: \
if (IVSIZE >= 8) \
XSRETURN_UV(i2d.i64); \
else \
XSRETURN_UNDEF; \
case 2: \
XSRETURN_PVN(i2d.str, 8); \
default: \
XSRETURN_UNDEF; \
} \
} \
else { \
mPUSHn(i2d.dbl); \
if (GIMME_V == G_ARRAY) { \
EXTEND(SP, 2); \
if (IVSIZE >= 8) \
mPUSHu(i2d.i64); \
else \
PUSHs(&PL_sv_undef); \
mPUSHp(i2d.str, 8); \
} \
} \
} \
void
rd_double(mt_state* state, int index = 0)
PREINIT:
int2dbl i2d;
PPCODE:
i2d = rd_double(state);
RETURN_I2D(items > 1);
void
_rd_double(int index = 0)
PREINIT:
int2dbl i2d;
PPCODE:
i2d = rd_double(NULL);
RETURN_I2D(items != 0);
IV
rd_iuniform32(mt_state* state, IV lower, IV upper);
ALIAS:
rd_iuniform64 = 1
rd_iuniform = 2
CODE:
#if IVSIZE >= 8
if (ix)
RETVAL = rds_liuniform(state, lower, upper);
#else
if (ix == 1)
XSRETURN_UNDEF;
#endif
else
RETVAL = rds_iuniform(state, (int32_t)lower, (int32_t)upper);
OUTPUT:
RETVAL
IV
_rd_iuniform32(IV lower, IV upper);
ALIAS:
_rd_iuniform64 = 1
_rd_iuniform = 2
CODE:
#if IVSIZE >= 8
if (ix)
RETVAL = rd_liuniform(lower, upper);
#else
if (ix == 1)
XSRETURN_UNDEF;
#endif
else
RETVAL = rd_iuniform((int32_t)lower, (int32_t)upper);
OUTPUT:
RETVAL
NV
rd_uniform(mt_state* state, NV lower, NV upper);
ALIAS:
rd_luniform = 1
CODE:
RETVAL = (ix == 0) ? rds_uniform(state, lower, upper)
: rds_luniform(state, lower, upper);
OUTPUT:
RETVAL
NV
_rd_uniform(NV lower, NV upper);
ALIAS:
_rd_luniform = 1
CODE:
RETVAL = (ix == 0) ? rd_uniform(lower, upper)
: rd_luniform(lower, upper);
OUTPUT:
RETVAL
NV
: rd_lnormal(mean, sigma);
OUTPUT:
RETVAL
NV
rd_triangular(mt_state* state, NV lower, NV upper, NV mode)
ALIAS:
rd_ltriangular = 1
CODE:
RETVAL = (ix == 0) ? rds_triangular(state, lower, upper, mode)
: rds_ltriangular(state, lower, upper, mode);
OUTPUT:
RETVAL
NV
_rd_triangular(NV lower, NV upper, NV mode)
ALIAS:
_rd_ltriangular = 1
CODE:
RETVAL = (ix == 0) ? rd_triangular(lower, upper, mode)
: rd_ltriangular(lower, upper, mode);
OUTPUT:
RETVAL
int
savestate(mt_state* state, SV* file_sv)
int
_savestate(SV* file_sv)
CODE:
RETVAL = savestate(NULL, file_sv);
OUTPUT:
RETVAL
int
loadstate(mt_state* state, SV* file_sv)
int
_loadstate(SV* file_sv)
CODE:
RETVAL = loadstate(NULL, file_sv);
OUTPUT:
RETVAL
SV*
getstate(mt_state* state)
CODE:
RETVAL = newSVpvn((char*)state, sizeof(mt_state));
OUTPUT:
RETVAL
SV*
_getstate()
CODE:
RETVAL = newSVpvn((char*)&mt_default_state, sizeof(mt_state));
OUTPUT:
RETVAL
void
setstate(mt_state* state, SV* sv_state)
PPCODE:
set_state_from_sv(sv_state, state);
void
_setstate(SV* sv_state)
PPCODE:
set_state_from_sv(sv_state, &mt_default_state);
BOOT:
{
HV *stash;
stash = gv_stashpv("Math::Random::MTwist", TRUE);
newCONSTSUB(stash, "HAS_UINT64_T", newSViv(HAS_UINT64_T));
newCONSTSUB(stash, "NVMANTBITS", newSViv(NVMANTBITS));
}
# vim: set ts=2 sw=2 sts=2 expandtab:
( run in 1.390 second using v1.01-cache-2.11-cpan-71847e10f99 )