如何在macos中获得drand48_r

How to get drand48_r in macos?

本文关键字:drand48 macos      更新时间:2023-10-16

我确实需要使用drand48_r生成器,但macosx中似乎没有。我已经寻找答案有一段时间了,但我唯一学到的是没有答案。但我需要它是线程安全的,所以有什么办法可以自己写吗?会是吗

struct drand48_data
{
unsigned short int __x[3];  /* Current state.  */
unsigned short int __old_x[3]; /* Old state.  */
unsigned short int __c;     /* Additive const. in congruential formula.  */
unsigned short int __init;  /* Flag for initializing.  */
unsigned long long int __a; /* Factor in congruential formula.  */
};
double drand48_r (unsigned short *_x) {
return erand48(_x);
}

主要是:

// declare state struct for drand48
drand48_data* _drand_structs = new drand48_data[omp_get_num_threads()];
#pragma omp parallel
cout << "Hello, World from " << omp_get_thread_num() << "/" << omp_get_num_threads() << " Random:" << (2.0 * drand48_r(_drand_structs[omp_get_thread_num()].__x) - 1) << endl;
return 0;

但drand_48总是返回-1。它怎么了,有什么想法吗?

在并行区域外调用omp_get_num_threads()总是返回1,因为只有一个线程(主线程)在这些区域外执行代码。您应该使用omp_get_max_threads()。初始化__x成员也是一个好主意。srand48(seed)的等价物是:

.__x[0] = 0x330E;
.__x[1] = (unsigned short)(seed & 0xffff);
.__x[2] = (unsigned short)(seed >> 16);

除此之外,drand48_r()drand48()可重入版本。请注意,可重入性线程安全性

如果您需要在每个线程中支持不同的常量,那么您可能应该直接从GLIBC复制drand48_r()的实现。