gpt4 book ai didi

perl - 为什么 $val > 2 ** randbits 时 rand($val) 不发出警告?

转载 作者:行者123 更新时间:2023-12-01 05:56:51 26 4
gpt4 key购买 nike

我正在使用 Strawberry Perl v5.16.2使用重复调用 int rand 1_000_000 来构造一些虚假数据.之后,相当困惑,我发现因为我的 perl 的 randbits=15 , 上面的表达式只会返回 2**1532768可能的值。

>perl -V:randbits
randbits='15';

我的问题是:
  • 为什么 use warnings; 当有人尝试使用 rand $val 时不返回警告在哪里 $val > 2 ** randbits ?
  • 为什么 perldoc rand 根本不提这个问题?有一个关于如何 "rand() is not cryptographically secure" 的附录.我相信这也值得附上建议的替代解决方案。

  • 设置

    我正在尝试创建一些假数据来测试一种算法,该算法用于对平均有 20 个重复的大量数据进行排序。这适用于 1,000 和 10,000 个条目,但是当我跳到 100 万个时,我发现我遗漏了很多唯一值。

    这似乎是统计上的不可能性。概率 p在 2000 万次拉取中不会选择小于 100 万的特定整数是 (999_999/1_000_000) ** 20_000_0002.06e-9 .所以不会选择任何整数的概率是 .2% .

    我迅速编写了另一个脚本,以确认我的假数据生成器没有缺陷:
    use strict;
    use warnings;

    use List::Util qw(sum max min);

    our $max_count = 1_000;

    my %count;

    while (1) {
    my $val = int rand 1_000_000;
    last if ++$count{$val} > $max_count;
    }

    my $sum = sum values %count;
    my $max = max values %count;
    my $min = min values %count;
    my $count = scalar keys %count;

    print "$sum interations. $count integers of expected 1mil with min $min, max $max\n";

    输出:
    28,958,579 interations.  32768 integers of expected 1mil with min 772, max 1001

    显然, 32,768是一个巨大的红旗,是 2 的力量,所以快速谷歌搜索 "perl rand does maximum 32768 integers" 返回以下有用资源:
  • What is wrong with perl's antique random number generator
  • How big can the argument to Perl's rand be? - Stack Overflow

  • 前者是讨论此问题所有不同方面的重要资源,并提供替换 rand use Math::Random::MT qw(rand); use Math::Random::MT::Auto qw(rand); .

    SO帖子提供 an answer 其中包括一个不需要安装新模块的解决方案,只需调用 rand两次以获得更多位。
    use Config;
    use constant RANDBITS => $Config{randbits};
    use constant RAND_MAX => 2**RANDBITS;

    sub double_rand {
    my $max = shift || 1;
    my $iv =
    int rand(RAND_MAX) << RANDBITS
    | int rand(RAND_MAX);
    return $max * ($iv / 2**(2*RANDBITS));
    }

    幸运的是,这两个都解决了我最初的问题。回顾一下,我很好奇......
  • rand 的替代品有更好的下降吗? ?
  • perldoc rand为什么没有两句附录提到这个问题?
  • 为什么warnings大于 2**randbits 的值不发出警告?如果有人想忽略警告,可能会有 no warnings 'rand'调用或直接调用没有值的 rand:val * rand .
  • 我是否错误地安装了 Strawberry Perl 以得到如此低的随机数?有没有办法提高这个值(value)?这样做是用户的责任吗?

  • 谢谢。

    最佳答案

    对于非加密目的,请使用 Math::Random::MT . The Mersenne Twister PRNG有很好的属性。

    您可以使用函数接口(interface)作为 rand 的替代品。内置:

    面向函数的界面:

    use Math::Random::MT qw(srand rand irand);
    # now use srand() and rand() as you usually do in Perl

    关于perl - 为什么 $val > 2 ** randbits 时 rand($val) 不发出警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22772578/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com