Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //./include/kaelygon/math/rand.h
- #ifndef KAELRAND_H
- #define KAELRAND_H
- //8-bit permuted congruential generator rorr + LCG
- //periods, total state bit count is KAELRAND_STATES*8 + 8
- //32-bit period: 2^11 * 127^3
- //24-bit period: 2^10 * 127^2
- //16-bit period: 2^9 * 127^1
- //8-bit states 0, since iteration loop requires at least 1 state
- //More shift,mul,add candidates at ./generated/validRorrLCG.txt
- #include <stdint.h>
- #include <stdlib.h>
- enum {
- KAELRAND_SHIFT = 1,
- KAELRAND_MUL = 37,
- KAELRAND_ADD = 57,
- KAELRAND_STATES = 3
- };
- typedef struct {
- uint8_t state[KAELRAND_STATES];
- uint8_t last; //latest output, contributes to period length
- }KaelRand;
- void kaelRand_seed(KaelRand *krand, char *cstr);
- uint8_t kaelRand(KaelRand *krand);
- uint16_t kaelRand_u16lcg(uint16_t seed);
- #endif
- //./include/kaelygon/math/rand.c
- #ifndef KAELRAND_C
- #define KAELRAND_C
- //8-bit permuted congruential generator rorr + LCG
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include "kaelygon/math/math.h"
- #include "kaelygon/math/rand.h"
- //Simple cstring to hash
- void kaelRand_hash(char* cstr, uint8_t *numArr, uint8_t arrLen){
- if(cstr==NULL || numArr==NULL || arrLen==0){return;}
- const uint8_t ASCII_START = 32;
- const uint8_t ASCII_END = 126;
- const uint8_t ASCII_SCALE = (0xFF) / (ASCII_END - ASCII_START)+1;
- //shift and scale ascii range 0 to 0xFF. Sum and wrap to mix
- uint8_t index = 0;
- uint8_t sum = 0;
- while(cstr[index] && (index!=0xFF)){
- sum += ((uint8_t)(cstr[index])-ASCII_START) * ASCII_SCALE;
- numArr[index%arrLen] = sum;
- index++;
- };
- }
- //Seed from string hash. NULL string = zero
- void kaelRand_seed(KaelRand *krand, char *cstr){
- if(krand==NULL){return;}
- memset(&krand->state,0,sizeof(uint8_t)*KAELRAND_STATES);
- if(cstr==NULL){return;}
- krand->last=(uint8_t)cstr[0]*KAELRAND_MUL+KAELRAND_ADD;
- kaelRand_hash( cstr, krand->state, KAELRAND_STATES );
- }
- //Iterate KaelRand states and output a pseudo random number
- //No null check as this is run in tight loops, CHECK SEPARATELY
- uint8_t kaelRand( KaelRand *krand ){
- for(uint8_t i=0; i<KAELRAND_STATES;i++){ //Cycle all states condotionally
- krand->state[i] = kaelMath_u8rorr(krand->state[i], KAELRAND_SHIFT) * KAELRAND_MUL + KAELRAND_ADD; //rorr LCG
- krand->last+= krand->state[i]; //mix with previous sum
- //early exit condition. Only breaking the cycle at 0 is necessary for full period.
- //the part after || results in effective 5/8 chance to skip next bytes
- //trade off for speed at cost off randomness quality
- if( krand->state[i]==0 || ((krand->state[i]&0b11111)!=0) ){
- break;
- }
- }
- return krand->last;
- }
- //other 16-bit RLCG parameters
- //{1, 95, 975}, // 0.316218
- //{2, 83, 89}, // 0.374768
- //{2, 61, 394}, // 0.513991
- //{1, 49, 112}, // 0.645737
- //16-bit full period RORR LCG
- kmath_t kaelRand_u16lcg(kmath_t seed){
- seed = kaelMath_rorr(seed,2);
- return seed * 83 + 89;
- }
- #endif
- //main
- //./tools/rorLCG-Testing.c
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <x86intrin.h>
- #include "../include/kaelygon/math/rand.h"
- #include <math.h>
- int main(){
- KaelRand randState;
- kaelRand_seed(&randState,"I am about to become a hash, hihii!");
- FILE *fptr;
- fptr = fopen("./generated/audio.pcm","wb");
- if(fptr==NULL){printf("open failed\n"); abort();}
- uint8_t num = 0;
- uint64_t startTime = __rdtsc();
- for(uint64_t i=0; i<(uint64_t)pow(2,24);i++){
- num = kaelRand(&randState);
- fwrite(&num,sizeof(uint8_t),1,fptr);
- }
- uint64_t endTime = __rdtsc();
- printf("time %.4f \n", (double)(endTime-startTime)/3700000000);
- fclose(fptr);
- printf("num %u \n", num);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement