Merge pull request #3191 from AchrafReyani/feat/libc-rand-r
feat(libc): implement rand_r
This commit is contained in:
commit
043aac6a4d
|
|
@ -143,15 +143,27 @@ int APS5_VABI __signbitf_nid_postfix(float x) { return std::signbit(x) ? 1 : 0;
|
|||
static std::mutex g_randLock;
|
||||
static std::uint32_t g_randState = 1;
|
||||
|
||||
int APS5_VABI rand_nid_postfix() {
|
||||
std::lock_guard lock(g_randLock);
|
||||
const std::int64_t x = static_cast<std::int64_t>(g_randState % 0x7ffffffeu) + 1;
|
||||
static int NextRand_nid_no_patch(std::uint32_t& state) {
|
||||
const std::int64_t x = static_cast<std::int64_t>(state % 0x7ffffffeu) + 1;
|
||||
std::int64_t next = 16807 * (x % 127773) - 2836 * (x / 127773);
|
||||
if (next < 0) next += 0x7fffffff;
|
||||
g_randState = static_cast<std::uint32_t>(next - 1);
|
||||
state = static_cast<std::uint32_t>(next - 1);
|
||||
return static_cast<int>(next - 1);
|
||||
}
|
||||
|
||||
int APS5_VABI rand_nid_postfix() {
|
||||
std::lock_guard lock(g_randLock);
|
||||
return NextRand_nid_no_patch(g_randState);
|
||||
}
|
||||
|
||||
int APS5_VABI rand_r_nid_postfix(unsigned int* state) {
|
||||
if (state == nullptr) throw std::invalid_argument("rand_r: null state");
|
||||
std::uint32_t value = *state;
|
||||
const int result = NextRand_nid_no_patch(value);
|
||||
*state = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
void APS5_VABI srand_nid_postfix(unsigned int seed) {
|
||||
std::lock_guard lock(g_randLock);
|
||||
g_randState = seed;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ float APS5_VABI atan2f_nid_postfix(float, float);
|
|||
float APS5_VABI hypotf_nid_postfix(float, float);
|
||||
double APS5_VABI hypot_nid_postfix(double, double);
|
||||
float APS5_VABI tanf_nid_postfix(float);
|
||||
int APS5_VABI rand_nid_postfix();
|
||||
void APS5_VABI srand_nid_postfix(unsigned int);
|
||||
int APS5_VABI rand_r_nid_postfix(unsigned int*);
|
||||
float APS5_VABI log10f_nid_postfix(float);
|
||||
float APS5_VABI logbf_nid_postfix(float);
|
||||
double APS5_VABI exp2_nid_postfix(double);
|
||||
|
|
@ -313,6 +316,18 @@ int main() {
|
|||
Require(std::abs(acosf_nid_postfix(0.5f) - 1.0471976f) < 0.000001f);
|
||||
Require(std::abs(atan2f_nid_postfix(1.f, -1.f) - 2.3561945f) < 0.000001f);
|
||||
Require(tanf_nid_postfix(0.f) == 0.f);
|
||||
unsigned int randomState = 1;
|
||||
Require(rand_r_nid_postfix(&randomState) == 33613 && randomState == 33613u);
|
||||
randomState = 0;
|
||||
Require(rand_r_nid_postfix(&randomState) == 16806 && randomState == 16806u);
|
||||
for (const unsigned int seed : {0u, 1u, 12345u, 0x7ffffffeu, 0xffffffffu}) {
|
||||
srand_nid_postfix(seed);
|
||||
randomState = seed;
|
||||
for (int step = 0; step < 8; ++step) Require(rand_r_nid_postfix(&randomState) == rand_nid_postfix());
|
||||
}
|
||||
bool threw = false;
|
||||
try { rand_r_nid_postfix(nullptr); } catch (...) { threw = true; }
|
||||
Require(threw);
|
||||
Require(hypot_nid_postfix(3.0, 4.0) == 5.0 && hypot_nid_postfix(-3.0, -4.0) == 5.0 && hypotf_nid_postfix(3.f, -4.f) == 5.f);
|
||||
Require(std::abs(hypot_nid_postfix(1e308, 1e308) / 1.4142135623730951e308 - 1.0) < 1e-15);
|
||||
Require(std::abs(hypotf_nid_postfix(2e38f, 2e38f) / 2.8284271e38f - 1.f) < 1e-6f);
|
||||
|
|
|
|||
Loading…
Reference in New Issue