Path: blob/main/contrib/arm-optimized-routines/math/test/rtest/random.c
48375 views
/*1* random.c - random number generator for producing mathlib test cases2*3* Copyright (c) 1998-2019, Arm Limited.4* SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception5*/67#include "types.h"8#include "random.h"910static uint32 seedbuf[55];11static int seedptr;1213void seed_random(uint32 seed) {14int i;1516seedptr = 0;17for (i = 0; i < 55; i++) {18seed = seed % 44488 * 48271 - seed / 44488 * 3399;19seedbuf[i] = seed - 1;20}21}2223uint32 base_random(void) {24seedptr %= 55;25seedbuf[seedptr] += seedbuf[(seedptr+31)%55];26return seedbuf[seedptr++];27}2829uint32 random32(void) {30uint32 a, b, b1, b2;31a = base_random();32b = base_random();33for (b1 = 0x80000000, b2 = 1; b1 > b2; b1 >>= 1, b2 <<= 1) {34uint32 b3 = b1 | b2;35if ((b & b3) != 0 && (b & b3) != b3)36b ^= b3;37}38return a ^ b;39}4041/*42* random_upto: generate a uniformly randomised number in the range43* 0,...,limit-1. (Precondition: limit > 0.)44*45* random_upto_biased: generate a number in the same range, but with46* the probability skewed towards the high end by means of taking the47* maximum of 8*bias+1 samples from the uniform distribution on the48* same range. (I don't know why bias is given in that curious way -49* historical reasons, I expect.)50*51* For speed, I separate the implementation of random_upto into the52* two stages of (a) generate a bitmask which reduces a 32-bit random53* number to within a factor of two of the right range, (b) repeatedly54* generate numbers in that range until one is small enough. Splitting55* it up like that means that random_upto_biased can do (a) only once56* even when it does (b) lots of times.57*/5859static uint32 random_upto_makemask(uint32 limit) {60uint32 mask = 0xFFFFFFFF;61int i;62for (i = 16; i > 0; i >>= 1)63if ((limit & (mask >> i)) == limit)64mask >>= i;65return mask;66}6768static uint32 random_upto_internal(uint32 limit, uint32 mask) {69uint32 ret;70do {71ret = random32() & mask;72} while (ret > limit);73return ret;74}7576uint32 random_upto(uint32 limit) {77uint32 mask = random_upto_makemask(limit);78return random_upto_internal(limit, mask);79}8081uint32 random_upto_biased(uint32 limit, int bias) {82uint32 mask = random_upto_makemask(limit);8384uint32 ret = random_upto_internal(limit, mask);85while (bias--) {86uint32 tmp;87tmp = random_upto_internal(limit, mask); if (tmp < ret) ret = tmp;88tmp = random_upto_internal(limit, mask); if (tmp < ret) ret = tmp;89tmp = random_upto_internal(limit, mask); if (tmp < ret) ret = tmp;90tmp = random_upto_internal(limit, mask); if (tmp < ret) ret = tmp;91tmp = random_upto_internal(limit, mask); if (tmp < ret) ret = tmp;92tmp = random_upto_internal(limit, mask); if (tmp < ret) ret = tmp;93tmp = random_upto_internal(limit, mask); if (tmp < ret) ret = tmp;94tmp = random_upto_internal(limit, mask); if (tmp < ret) ret = tmp;95}9697return ret;98}99100101