C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了C中的随机整数,与整数运算相比,rand()%N有多糟糕?它的缺点是什么?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
编辑:
我的问题是:rand()%N被认为非常糟糕,而整数算术的使用被认为是优越的,但我看不出两者之间的区别.

人们总是提到:

> rand()%N中的低位不是随机的,
> rand()%N是非常可预测的,
>您可以将它用于游戏,但不能用于加密

有人可以解释这些问题是否属于这种情况以及如何看待?

低位的非随机性的想法应该使我所展示的两种情况的PE不同,但实际情况并非如此.

我想像我一样的人总是会避免使用rand()或rand()%N,因为我们总是被教导它非常糟糕.我很想知道c rand()%N生成的“错误随机整数有效.这也是Ryan Reich在How to generate a random integer number from within a range年回答的后续行动.

说实话,那里的解释听起来很有说服力;尽管如此,我还以为我试一试.所以,我以非常天真的方式比较分布.我为不同数量的样本和域运行两个随机生成器.我没有看到计算密度而不是直方图的重点,所以我只计算直方图,只是通过观察,我会说它们看起来都一样均匀.关于提出的另一点,关于实际的随机性(尽管是均匀分布的).我 – 再次天真地计算这些运行的置换熵,对于两个样本集都是相同的,这告诉我们两者之间关于事件排序没有区别.

所以,出于很多目的,在我看来rand()%N会很好,我们怎么能看到它们的缺陷呢?

在这里,我向您展示了一种非常简单,低效且不太优雅(但我认为正确)的计算这些样本的方法,并将直方图与排列熵一起得到.
对于不同数量的样本,我在{5,10,25,50,100}中显示了域(0,i)和i的图:

我想在代码中没什么可看的,所以我会留下C和matlab代码用于复制目的.

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main(int argc,char *argv[]){
        unsigned long max = atoi(argv[2]);
        int samples=atoi(argv[3]);
        srand(time(NULL));
        if(atoi(argv[1])==1){
                for(int i=0;i<samples;++i)
                        printf("%ld\n",rand()%(max+1));

        }else{
                for(int i=0;i<samples;++i){
                        unsigned long
                        num_bins = (unsigned long) max + 1,num_rand = (unsigned long) RAND_MAX + 1,bin_size = num_rand / num_bins,defect   = num_rand % num_bins;

                        long x;
                        do {
                                x = rand();
                        }
                        while (num_rand - defect <= (unsigned long)X);
                        printf("%ld\n",x/bin_sizE);
                }
        }
        return 0;
}

这里是Matlab代码来绘制这个并计算PE(我从中获取的排列的递归:https://www.mathworks.com/matlabcentral/answers/308255-how-to-generate-all-possible-permutations-without-using-the-function-perms-randperm):

system('gcc randomTest.c -o randomTest.exe;');
max = 100;
samples = max*10000;
trials = 200;
system(['./randomTest.exe 1 ' num2str(maX) ' ' num2str(samples) ' > file1'])
system(['./randomTest.exe 2 ' num2str(maX) ' ' num2str(samples) ' > file2'])
a1=load('file1');
a2=load('file2');
uni = figure(1);
title(['Samples: ' num2str(samples)])
subplot(1,3,1)
h1 = histogram(a1,max+1);
title('rand%(max+1)')
subplot(1,2)
h2 = histogram(a2,max+1);
title('Integer arithmetic')
as=[a1,a2];
ns=3:8;
H = nan(numel(ns),size(as,2));
for op=1:size(as,2)
    x = as(:,op);
    for n=ns
        sequenceOcurrence = zeros(1,factorial(n));
        sequences = myperms(1:n);
        sequencesArrayIdx = sum(sequences.*10.^(size(sequences,2)-1:-1:0),2);
        for i=1:numel(X)-n
            [~,sequenceOrder] = sort(x(i:i+n-1));
            out = sequenceOrder'*10.^(numel(sequenceOrder)-1:-1:0).';
            sequenceOcurrence(sequencesArrayIdx == out) = sequenceOcurrence(sequencesArrayIdx == out) + 1;
        end
        chunks = length(X) - n + 1;
        ps = sequenceOcurrence/chunks;
        hh = sum(ps(logical(ps)).*log2(ps(logical(ps))));
        H(n,op) = hh/log2(factorial(n));
    end
end
subplot(1,3)
plot(ns,H(ns,:),'--*','linewidth',2)
ylabel('PE')
xlabel('Sequence length')
filename = ['all_' num2str(maX) '_' num2str(samples) ];
export_fig(fileName)

解决方法

由于模数运算的方式如果N与RAND_MAX相比显着,那么%N将使得它更有可能获得某些值而不是其他值.想象一下,RAND_MAx是12,N是9.如果分布是好的,那么获得0,1或2之一的几率是0.5,获得3,4,5,6,7,8之一的机会是0.5.结果是你获得0而不是4的可能性是两倍.如果N是RAND_MAX的精确分频器,则不会发生这种分布问题,并且如果N与RAND_MAX相比非常小,则问题变得不那么明显. RAND_MAX可能不是特别大的值(可能是2 ^ 15 – 1),这使得这个问题比你预期的更糟. do(rand()* n)/(RAND_MAX 1)的替代方案也不会给出均匀分布,但是,每个m值(对于某些m)将更可能发生而不是更可能发生值都在分布的低端.

如果N是RAND_MAX的75%,则分布的底部三分之一的值是前三分之二的值的两倍(因为这是额外值映射到的位置)

rand()的质量取决于您所使用的系统的实现.我相信有些系统的实现很差,OS Xs手册页声明rand已经过时了. Debian手册页说明如下:

Linux C Library中的rand()和srand()版本使用相同的版本随机生成随机(3)和srandom(3),所以低阶比特应该与高阶比特一样随机.但是,老年人rand()实现,以及不同的当前实现系统中,低阶位的随机性要小于订单位.请勿在应用程序中使用此功能便携式,需要良好的随机性. (改为使用随机(3).)

大佬总结

以上是大佬教程为你收集整理的C中的随机整数,与整数运算相比,rand()%N有多糟糕?它的缺点是什么?全部内容,希望文章能够帮你解决C中的随机整数,与整数运算相比,rand()%N有多糟糕?它的缺点是什么?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。