X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/b2e3cab6544444137fe7aadee2a991adbfde97c4..1c3b0c0e6f9339e76e42f6393e554c7dfc58e205:/t/rng-test.c diff --git a/t/rng-test.c b/t/rng-test.c new file mode 100644 index 0000000..3f4cf32 --- /dev/null +++ b/t/rng-test.c @@ -0,0 +1,80 @@ +/* + * Simple random number generator for testing. + * Copyright © 2022 Nick Bowler + * + * Directly compare the test lib RNG against the reference implementation. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "rng.c" +#include "xos256p.c" + +int main(void) +{ + unsigned long long seed_state = 0xdeadbeeff00dcafe; + unsigned long long test_result, ref_result; + unsigned long long ref_state[4], test_state[4]; + int i, ret = 0; + + printf("1..200\n"); + for (i = 0; i < 100; i++) { + s[0] = ref_state[0] = test_state[0] = splitmix64(&seed_state); + s[1] = ref_state[1] = test_state[1] = splitmix64(&seed_state); + s[2] = ref_state[2] = test_state[2] = splitmix64(&seed_state); + s[3] = ref_state[3] = test_state[3] = splitmix64(&seed_state); + + ref_result = next(); + test_result = xoshiro256p(test_state); + + if (ref_result != test_result) { + printf("not ok %d rng output\n", 2*i+1); + printf("# Failed, unexpected result\n"); + printf("# with initial state %llx %llx %llx %llx\n", + ref_state[0], ref_state[1], + ref_state[2], ref_state[3]); + printf("# received: %llx\n", test_result); + printf("# expected: %llx\n", ref_result); + ret = EXIT_FAILURE; + } else { + printf("ok %d rng output\n", 2*i+1); + } + + if (s[0] != test_state[0] || s[1] != test_state[1] + || s[2] != test_state[2] || s[3] != test_state[3]) + { + printf("not ok %d rng state update\n", 2*i+2); + printf("# Failed, state update differed\n"); + printf("# with initial state %llx %llx %llx %llx\n", + ref_state[0], ref_state[1], + ref_state[2], ref_state[3]); + printf("# received: %llx %llx %llx %llx\n", + test_state[0], test_state[1], + test_state[2], test_state[3]); + printf("# expected: %llx %llx %llx %llx\n", + (unsigned long long)s[0], + (unsigned long long)s[1], + (unsigned long long)s[2], + (unsigned long long)s[3]); + ret = EXIT_FAILURE; + } else { + printf("ok %d rng state update\n", 2*i+2); + } + } + + return ret; +}