【问题标题】:Whats wrong with rand function in C [duplicate]C中的rand函数有什么问题[重复]
【发布时间】:2022-01-17 18:06:13
【问题描述】:

在 C 中生成随机数的结果不好的原因是什么?请参阅下面的代码。结果应该是 0 - 1 之间的数字。但是当我打印随机数时,结果是:Doba prichodu: 690522220 n 次。是的,我正在使用 srand(time(NULL));

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>

.
.
.

pthread_t vlakna[n];
    for (int i = 0; i < n; i++) {
       // double dobaPrichodu = (rand() / (double)RAND_MAX) * 7 + 1; // 1 - 8
        double dobaPrichodu = rand()/(double)RAND_MAX;
        printf("Doba prichodu: %d\n", dobaPrichodu);
        argsZakaznici[i] = (ARGUMENTS_ZAKAZNIK){&args, i+1, dobaPrichodu};
        pthread_create(&vlakna[i], NULL, Zakaznik, &argsZakaznici[i]);
    } 

【问题讨论】:

  • 如果您的编译器没有警告您错误的替换(%d 用于double),您应该考虑升级到最新版本并打开所有警告。大多数现代编译器应该能够发现此类错别字。

标签: c random pthreads unistd.h


【解决方案1】:

对于double dobaPrichodu,您应该使用:

printf("Doba prichodu: %lf\n", dobaPrichodu);

当您改用%d 时,函数printf 会尝试将dobaPrichodu 中传递的数据读取为int 而不是double。

因此,您不仅会打印出错误的数据,而且由于这两种类型的大小甚至不同,您还会得到程序的一种未定义行为(即,它可能在不同的平台)。

例如:

在 int 的大小为 4 个字节,double 的大小为 8 个字节的 Big Endian 平台上,您将读取 dobaPrichodu 的前半部分并将其打印为整数。

在 int 的大小为 4 个字节且 double 的大小为 8 个字节的 Little Endian 平台上,您将得到 dobaPrichodu 的后半部分以整数形式读取和打印。

【讨论】:

  • 天啊...非常感谢,我认为 %d 代表十进制。
  • @PeterKulas "%d" 确实代表 十进制。
  • bbbbbbbbb,不寻常,但int 的字节序不必与double 的字节序相同。 double 和 int may get passed as ...` 通过不同的方式争论。 “你会得到 dobaPrichodu 的前半部分/后半部分被读取并打印为整数。”是未定义行为的许多可能影响中的两个。
  • 对于printf(),%lf 中的l 是不必要的。此外,无论对象的字节顺序和大小如何,行为都是未定义的,因为这是定义 printf() 的方式。假设参数是在堆栈上传递的(然后试图推断整数和浮点参数的潜在重叠)是一个错误,因为在理智的体系结构上,函数参数是在寄存器中传递的(除非你传递的参数太多以适应),在现代架构上,浮点寄存器通常与整数寄存器不相交。
猜你喜欢
  • 1970-01-01
  • 2012-02-05
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
相关资源
最近更新 更多