Merge pull request #3191 from AchrafReyani/feat/libc-rand-r

feat(libc): implement rand_r
This commit is contained in:
Dean 2026-10-11 19:05:27 +13:00 committed by GitHub
commit 043aac6a4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 4 deletions

View File

@ -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;

View File

@ -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);