【问题标题】:C - Random value +/- from previous valueC - 随机值 +/- 上一个值
【发布时间】:2021-12-17 10:26:19
【问题描述】:

我试图用 C 语言编写一些代码来模拟与先前值相比 +/- 4 的温度波动,但是我在任一方向都得到了一些疯狂的跳跃。

该程序是多线程的,但是,即使单独测试也会产生同样的错误结果。

我尝试了代码的几种变体,认为这与代码的评估方式有关,但我的错误但它们最终都是一样的。我的代码如下:

int main(){
    srand(1); //Just for testing and predictability of outcome
    //short int temp = 20 + rand() / (RAND_MAX / 30 - 20 + 1) + 1; Initially I was initialising it at a random value between 20-30, but chose 20 for testing purposes
    short int temp = 20;
    short int new_temp, last_temp, new_min, new_max;
    last_temp = temp;
    for(int i = 0; i < 20; i++){
        //last_temp = temp; At first I believed it was because last_temp wasn't being reassigned, however, this doesn't impact the end result
        new_min = last_temp - 4;
        new_max = last_temp + 4;
        //new_temp = (last_temp-4) + rand() / (RAND_MAX / (last_temp + 4) - (last_temp - 4) + 1) + 1; I Also thought this broke because they last_temp was being changed with the prior math in the equations. Still no impact
        new_temp = new_min + rand() / (RAND_MAX / new_max - new_min + 1) + 1;

        printf("Temperature is %d\n", new_temp);
    }
    
    return 0;
}

产生这样的结果。

Temperature is 37
Temperature is 26
Temperature is 35
Temperature is 36
Temperature is 38

如您所见,第一个温度读数应该在 16-24 的范围内,但它会增加 17 到 37,我不知道为什么。任何见解将不胜感激。或者,谁能为我提供一种简洁的方法来模拟随机 +/- 而不必使用大量嵌入式 if 语句?

【问题讨论】:

  • 这里缺少什么:/+ 之间的RAND_MAX / + new_max
  • 更简单的方法是生成 -4 到 4 之间的随机增量。
  • 要开始调试此问题,您需要做的第一件事是分解您的复杂计算。添加几个中间变量来保存计算双方的结果,以便您可以在调试器中单步执行并查看正在完成的计算。如果您不知道如何使用调试器,那么现在是学习的好时机。它是编码人员工具箱中用于查找逻辑错误或跟踪执行流程的最佳工具。
  • the first temperature reading should be within the range of 16-24,为什么?是什么让您认为这是您计算的预期结果?
  • 本网站使用问题/答案格式 -- 请不要编辑问题以包含答案。如果您想发布固定版本,请将其发布为答案。 (并解释修复了什么)。

标签: c random


【解决方案1】:

这段代码有两个问题:

  1. rand()用法
  2. last_temp 值不会在每次迭代中更新

和用法

rand() 返回一个介于 0 和 RAND_MAX 之间的值。您想将此值限制在 [0,8] 中并将其添加到 new_min,以便将 new_temp 限制在 [last_temp-4,last_temp+4], ie [new_min,new_min+8] 中。

为此,您使用% 运算符。通过执行rand() % 9,您将随机值限制在 0 到 8 之间。因此,new_temp 值应为:new_temp = new_min + rand() % 9

last_temp 更新

您需要在分配 new_temp 值后更新 last_temp 值,如下所示:

new_temp = new_min + rand() % 9;
last_temp = new_temp;

所以,你的 for 循环最终应该是这样的:

for(int i = 0; i < 20; i++){
    new_min = last_temp - 4;
    new_max = last_temp + 4;
    new_temp = new_min + rand() % 9;
    last_temp = new_temp;

    printf("Temperature is %d\n", new_temp);
}

并且代码可以最小化成这样:

int main() {
    srand(1); //Just for testing and predictability of outcome
    short int temp = 20; //or 20 + rand()%11 for values in [20,30] range
    for(int i = 0; i < 20; i++) {
        temp += -4 + rand() % 9;
        printf("Temperature is %hd\n", temp);
    }
    return 0;
}

结果为:

Temperature is 23
Temperature is 25
Temperature is 22
Temperature is 21
Temperature is 18
Temperature is 21
Temperature is 19
Temperature is 19
Temperature is 16
Temperature is 17
Temperature is 15
Temperature is 14
Temperature is 12
Temperature is 11
Temperature is 10
Temperature is 12
Temperature is 12
Temperature is 10
Temperature is 10
Temperature is 6

【讨论】:

  • 我在更新帖子之前没有看到您的评论。这似乎是实现我正在寻找的结果的更好方法。谢谢
  • 使用 rand() % 8 将产生 0 到 7 之间的 8 个值,您可能希望使用 rand() % 9。但实际上你不会,因为使用模算术受modulo bias 的约束。在这种情况下,这可能还不够重要,但如果您想要一个真正均匀的分布,则需要做一些工作。
  • 感谢您的 cmets!我将答案更改为使用rand() % 9。关于模偏差,RAND_MAX越大,偏差越小。
猜你喜欢
  • 1970-01-01
  • 2018-02-10
  • 2013-01-06
  • 2015-04-01
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多