There may be a big bug in Practrand 0.94 and 0.95.
The results are not the same in the Windows Version (32 or 64 bits) and Unix version.
Code used :
~~~
/
* minimal-6502.c
*
* C version of the minimal-6502.asm code for testing
*
* (C) Arlet Ottens 2023 arlet@c-scape.nl
/
#define EOR( a, b ) \
do { \
a ^= (b); \
} while (0)
#define ADD( a, b ) \
do { \
x = a + (b); \
a = x; \
} while (0)
#define ADC( a, b ) \
do { \
x = a + (b) + (x >> 8) % 2; \
a = x; \
} while (0)
int main( void )
{
static char buf[65536];
uint8_t s0 = 0, s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0;
int x;
setvbuf( stdout, buf, _IOFBF, sizeof(buf) );
while( 1 )
{
ADD( s0, 0x45 );
ADC( s1, s0 );
ADC( s2, s1 );
ADC( s3, s2 );
EOR( s4, s3 );
ADC( s4, s5 );
ADC( s5, s4 );
EOR( s5, s2 );
putchar( s5 );
}
}
Footer
Result with Practrand Windows :
minimal.exe | RNG_test32.exe stdin8 -tlmin 1MB
rng=RNG_stdin8, seed=unknown
length= 1 megabyte (2^20 bytes), time= 0.1 seconds
Test Name Raw Processed Evaluation
DC6-9x1Bytes-1 R= +9.3 p = 4.3e-5 suspicious
Gap-16:A R= +7.3 p = 1.1e-5 suspicious
Gap-16:B R= +32.1 p = 1.4e-24 FAIL !!
FPF-14+6/16:(0,14-4) R=+179.6 p = 1.1e-146 FAIL !!!!!
FPF-14+6/16:all R=+114.2 p = 1.9e-96 FAIL !!!!!
[Low1/8]BCFN(2+0,13-9,T) R= +14.7 p = 1.9e-4 mildly suspicious
[Low1/8]BCFN(2+1,13-9,T) R= +27.8 p = 2.3e-7 very suspicious
[Low1/8]BCFN(2+2,13-9,T) R= +22.6 p = 3.4e-6 suspicious
...and 48 test result(s) without anomalies
minimal.exe | RNG_test32.exe stdin8
RNG_test using PractRand version 0.94
RNG = RNG_stdin8, seed = unknown
test set = core, folding = standard (8 bit)
rng=RNG_stdin8, seed=unknown
length= 32 megabytes (2^25 bytes), time= 2.4 seconds
Test Name Raw Processed Evaluation
BCFN(2+0,13-4,T) R= +96.2 p = 5.7e-42 FAIL !!!
BCFN(2+1,13-4,T) R= +93.6 p = 7.9e-41 FAIL !!!
BCFN(2+2,13-5,T) R=+104.9 p = 2.9e-41 FAIL !!!
BCFN(2+3,13-5,T) R=+105.1 p = 2.5e-41 FAIL !!!
BCFN(2+4,13-5,T) R= +88.2 p = 1.0e-34 FAIL !!!
BCFN(2+5,13-6,T) R=+103.5 p = 6.9e-36 FAIL !!!
BCFN(2+6,13-6,T) R=+106.3 p = 7.8e-37 FAIL !!!
BCFN(2+7,13-7,T) R=+114.8 p = 3.7e-35 FAIL !!!
BCFN(2+8,13-8,T) R=+125.3 p = 9.9e-33 FAIL !!!
BCFN(2+9,13-8,T) R=+126.4 p = 5.1e-33 FAIL !!!
BCFN(2+10,13-9,T) R=+177.0 p = 6.9e-41 FAIL !!!
BCFN(2+11,13-9,T) R=+172.2 p = 8.1e-40 FAIL !!!
DC6-9x1Bytes-1 R= +89.2 p = 3.1e-59 FAIL !!!!
Gap-16:A R= +84.6 p = 6.0e-69 FAIL !!!!
Gap-16:B R=+519.8 p = 1.6e-427 FAIL !!!!!!!
FPF-14+6/16:(0,14-0) R= +4220 p = 8e-3887 FAIL !!!!!!!!
FPF-14+6/16:(1,14-1) R=+190.4 p = 1.8e-168 FAIL !!!!!
FPF-14+6/16:(2,14-2) R=+133.6 p = 1.2e-116 FAIL !!!!!
FPF-14+6/16:(3,14-2) R=+174.7 p = 1.3e-152 FAIL !!!!!
FPF-14+6/16:(4,14-3) R=+122.6 p = 2.9e-107 FAIL !!!!!
FPF-14+6/16:(5,14-4) R= +87.3 p = 3.1e-71 FAIL !!!!
FPF-14+6/16:(6,14-5) R= +63.0 p = 4.4e-52 FAIL !!!!
FPF-14+6/16:(7,14-5) R= +38.4 p = 1.0e-31 FAIL !!!
FPF-14+6/16:(8,14-6) R= +17.2 p = 3.5e-13 FAIL
FPF-14+6/16:(9,14-7) R= +44.8 p = 1.7e-35 FAIL !!!
FPF-14+6/16:all R= +3043 p = 2e-2855 FAIL !!!!!!!!
FPF-14+6/16:cross R= +46.7 p = 3.0e-37 FAIL !!!
mod3n(5):(0,9-2) R= +19.6 p = 8.3e-11 VERY SUSPICIOUS
[Low1/8]BCFN(2+0,13-6,T) R=+215.7 p = 2.5e-74 FAIL !!!!
[Low1/8]BCFN(2+1,13-6,T) R=+207.2 p = 2.2e-71 FAIL !!!!
[Low1/8]BCFN(2+2,13-6,T) R=+194.1 p = 6.8e-67 FAIL !!!!
[Low1/8]BCFN(2+3,13-6,T) R=+205.5 p = 7.9e-71 FAIL !!!!
[Low1/8]BCFN(2+4,13-7,T) R=+252.1 p = 1.8e-76 FAIL !!!!
[Low1/8]BCFN(2+5,13-8,T) R=+325.0 p = 2.0e-83 FAIL !!!!
[Low1/8]BCFN(2+6,13-8,T) R=+316.7 p = 2.5e-81 FAIL !!!!
[Low1/8]BCFN(2+7,13-9,T) R=+329.0 p = 4.7e-75 FAIL !!!!
[Low1/8]BCFN(2+8,13-9,T) R=+342.0 p = 5.8e-78 FAIL !!!!
[Low1/8]DC6-9x1Bytes-1 R= +25.7 p = 2.9e-14 FAIL !
[Low1/8]FPF-14+6/16:all R= +6.4 p = 2.2e-5 mildly suspicious
[Low1/8]FPF-14+6/16:cross R= +32.8 p = 2.1e-28 FAIL !!!
...and 53 test result(s) without anomalies
** BUT NO ERRORS with UNIX version compiled on Raspberry Pi.**
./minimal | rng_test stdin8RNG_test using PractRand version 0.94
RNG = RNG_stdin8, seed = unknown
test set = core, folding = standard (8 bit)
rng=RNG_stdin8, seed=unknown
length= 8 megabytes (2^23 bytes), time= 2.9 seconds
no anomalies in 76 test result(s)
rng=RNG_stdin8, seed=unknown
length= 16 megabytes (2^24 bytes), time= 6.6 seconds
no anomalies in 84 test result(s)
rng=RNG_stdin8, seed=unknown
length= 32 megabytes (2^25 bytes), time= 12.2 seconds
no anomalies in 93 test result(s)
rng=RNG_stdin8, seed=unknown
length= 64 megabytes (2^26 bytes), time= 23.1 seconds
no anomalies in 99 test result(s)
Pretty sure that's a bug in your RNG's portability, not PractRand's. At a quick glance, your ADC implementation is bugged, though I don't quite see how that bug could lead to the results you see. Perhaps another bug is responsible.... actually, are you sure your RNG output isn't getting mangled by CR/LF issues somehow? That's what that looks like to me.
If you still think PractRand is responsible, eliminate your RNG's portability as a potential source by saving its output to a file and checking that that file produces different output across platforms for PractRand.
Thanks, this is indeed the problem. The author of the random algo found the problem.
Every '0a' byte gets translated to '0d 0a' on the pipe.
Last edit: Greg Owens 2023-04-16
I would also suggest changing "(x >> 8) % 2" to "((x >> 8) & 1)".
They may look equivalent, but x is declared as a signed type, and modulus operations on signed types can result in negative values in C/C++. That never actually comes up in practice here because the sign bit of x is always clear for the code as-is, but the compiler won't figure that out and will add extra logic to handle negative values correctly on each modulus. Plus if the algorithm ever gets adjusted in a way that does allow the sign bit to be set then ADC will return garbage results.