Rand函数使用和对补码的理解

下面是在牛客网看到的一道题;

//假设这n个数的序号依次为0,1,2,...,n-1,数组名为num

void knuth1(int* pNum, int m, int n){srand((unsigned int)time(0));for (int i=0; i<n; i++){if (rand()%(n-i) < m)//rand()%(n-i)的取值范围是[0, n-i){cout << pNum[i] << endl;m--;}}}

这是牛客网上的一道题,目的是从n个数中可放回地随机抽取m个数字。注意数字是可放回的,所以n个数字每一个数字被cout的概率都是m/n。当i取0,rand()%(n-i)的取值在是[0,n-1]范围随机分布,小于m的概率自然是m/n。当i取1,随机数的范围在[0,n-2],共n-1个取值。这时m的值要取决于i=0时有没有输出,所以可以用全概率公式计算。

这里想说的不是这道题本身,而是这个rand()函数。Rand()函数括号内是没有参数的,直接返回[0,RAND_MAX]的随机整数。但需要注意的是rand产生的是伪随机数,用线性同余法实现,依然是一个有限状态转换机,依然有周期(周期很长),所以当我们再一次调用这个函数,得到的结果相同,这在我们调试的时候很方便,但如果需要产生真正的随机数就需要srand来设置随机种子了。void srand (unsigned int seed);直接调用rand时,种子的值默认是1.要得到真正的随机数,每次设置的种子也应该不一样,我们通常使用time(0)作为种子,即把系统时间作为种子,保证了不同时刻得到的种子是不一样的。

在matlab中,rand函数就可以直接得到真正的随机数。为了在不同时刻运行函数时得到相同的随机数,便于调试,我们需要把随机数生成器初始化:RAND('state',0)。但是这一用法在新的matlab版本中不再支持,而推荐使用RNG。

在编译器中可看到RAND_MAX是一个宏定义,为0x7fff,也就是二进制的15位1. 百度百科中有:(C11)标准中未规定 RAND_MAX 的具体数值。但该标准规定了RAND_MAX 的值应至少为32767,最大为2147483647.这就引出了一个问题:int型明明在32位系统和64位系统中都占4字节,为什么这里产生的随机数的最大值只是15位全1的二进制和31位全1的二进制?其实,这就是带符号的short int型和int型的正数的最大值。于是,就有了第二个,也是很基本的一个问题,int型表示的范围是什么,正整数和负整数都是怎么表示的?(惭愧)

我们以一个字节长度为例。先不用管书上所强行灌输的数目符号位,原码,补码,我们从头开始,自己试着解决问题。8bit编码方式有2的8次方共256种,在图像中可以表示[0,255]的灰度级,在图像中像素取值只能是0或者正数,在计算机中,我们当然还需要表示负数,那么负数(先研究负整数)是怎么表示的呢?一个最自然而然的方式是把256种编码方式的一部分表示正数,一部分表示负数,一部分表示0.我们把0000 0001~01111 1111这一部分用来表示正整数,因为这一部分从0开始,是最符合我们数数的习惯的。那么现在的问题就是如何把剩下的表示负数。

首先,我们可以观察到剩下的部分除了0000 0000,最高位都是1,这就可以解释,为什么最高位的1来表示负数。那么1000 0000~1111 1111到底和负数是怎么对应的呢?一个理所当然的思路是1111 1111=-1*(0111 1111)=-127。我们来验证一下,1111 1111+0111 1111=0?明显不等于,但同时也给了我们一个思路,可以利用已有的正整数表达方法和绝对值相等的正负数之和为0的特点求负整数的表达方式。-1的二进制形式等于

0000 0000-0000 0001=1111 1111+0000 0001-0000 0001=1111 1111

于是我们知道,1111 1111对应的是-1.上面的式子还告诉了我们更多:0000 0000可以写做全1的数再加1,进位舍去就是全0.并且我们发现,将0拆分成全1和1的和,这样我们求-A的补码=全1-A+1,全1和二进制的加减都相对于异或,也就是取反,所以我们也终于得到了所谓的求负数补码的方法:按位取反再加1.

于是我们可以得到-2的补码:1111 1111+0000 0001-0000 0010=1111 1110

现在再考虑几个特殊的数,128=1000 0000,-128的补码=1000 0000,可见自然数128=-128的补码形式,由于我们已经规定了最高位是符号位,符号位1表示负数,所以0~255是代表补码时只有-128,没有128.于是我们也得到了所谓的一字节带符号整数取值范围[-128,127].

这样,我们得到规律,原来的0~255的数被分成两部分,[0,127]是递增的正数,和原来的表示方法一样,之后的数代表负数,也是递增。

到这里我们依然没有解释一句话,补码是为了让计算机把减法当做加法来做。其实,我们数轴首尾相接形成一个圆就好理解了。刚才我们也提到了,计算机中的加法超过长度会高位舍去,这其实意味着计算机中的数字是闭环的状态机。无论是加还是减,都是在这个闭环里面移位,只不过是逆时针还是顺时针罢了。我们把时钟的十二点位置看作是0/255,加法看作是顺时针移位(蓝色曲线),减法是逆时针(黄色曲线),这样六点钟附近是加数和减数绝对值最大的位置。为了避免减法(逆时针),我们可以顺时针移动相比于逆时针较大的角度达到相同的效果。逆时针转动30度就相当于顺时针转动330度,而330度就可以用时钟上的刻度来衡量,即0~255就是时钟的刻度。330度就是30度的补角,这也是补码的来历。

在查阅关于rand的使用的过程中,看到了一个例子,产生[0,10]之间的随机数:

#include<stdlib.h>int main(){int i,j;for(i=0; i<10; i++){j=1+(int)(10.0 * rand()/(RAND_MAX+1.0));printf("%d ",j);}}

 

产生介于 1 到 10 间的随机数值。这里的问题是为什么要加1.0?我的理解是如果分母取RAND_MAX,那么随机数范围就被归一化到[0,1],乘10后范围是[0,10],而我们的目标是先取得[0,9]的随机数再加1才能满足要求。注意到这里的加法和乘法都是float型,最后被强制转换成int型,其实这才是关键。分母取(最大值+1),使得随机数归一化后无法取到1,乘10之后范围是[0,10),最大值在9和10之间。而int强制转换是直接取浮点数的整数部分,这样我们就得到了范围在[0,9]的随机数。

P.s 浮点数到整型的转换,除了直接取整数部分,还有ceil函数和floor函数。Floor函数是取小于等于浮点数的整数,这一点与直接取整数部分在浮点数是负数时结果有区别。

最后,关于归一化方法和使用线性同余法得到想要的范围内的随机数的区别,有人说是前者是在多次随机出来的结果,前者理论上会更平均,而后者仅仅是和10求余得到的结果,没前面的结果来得平均。关于这个说法还不是很懂,有空可以再研究一下线性同余法。

Reference:

  1. rand函数https://blog.csdn.net/cmm0401/article/details/54599083
  2. 醍醐灌顶https://blog.csdn.net/wenxinwukui234/article/details/42119265
  3. 类型转换https://zhidao.baidu.com/question/1964506016596059780.html
  4. 牛客网:https://www.nowcoder.com/questionTerminal/12796031452e4ced8a16255bb02c4168
  5. 最后https://zhidao.baidu.com/question/561525713.html?qbl=relate_question_0&word=rand%20%BC%D31

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/493672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习巨头Yoshua Bengio清华演讲: 深度学习通往人类水平人工智能的挑战

来源&#xff1a;专知摘要&#xff1a;2018年11月7日晚&#xff0c;被称为“深度学习三巨头”之一的蒙特利尔大学计算机科学与运算研究系教授Yoshua Bengio在清华大学做了《深度学习抵达人类水平人工智能所面临的挑战&#xff08;Challenges for Deep Learning towards Human-L…

了解GAN网络

GAN网络&#xff0c;第一次听说它就不明觉厉。其他网络都是对输入图像进行某种处理&#xff0c;得到某种特定的输出。而GAN网络居然可以“无中生有”&#xff0c;无论是去除马赛克&#xff0c;还是换脸&#xff0c;还是对灰度图像上色&#xff0c;都显得不可思议&#xff0c;怎…

新能源汽车:大变革催生十万亿市场空间

来源&#xff1a;新时代证券&#xff08;开文明&#xff09;新能源汽车发展空间巨大&#xff0c;随着新能源汽车性能提升以及痛点的改善&#xff0c;新能源汽车带来的冲击越来越大&#xff0c;渗透率随之提升。根据BNEF预测&#xff0c;到2025年全球新能源汽车的销量将达到1100…

dlib+vs2013+opencv实现人脸特征点检测

刷知乎的时候发现dlib做特征点检测和人脸识别的效果都好于OpenCV&#xff0c;就想着动手玩一下。没想到也是遇坑重重。 首先&#xff0c;在官网 install命令和setup.py文件进行安装时报错&#xff0c;先是报错cmake没有找到&#xff0c;添加了环境变量之后仍然报错c11需要在vs…

对号入座,看看未来几年机器人是否会取代你的工作

来源&#xff1a;资本实验室摘要&#xff1a;面对未来&#xff0c;你是否准备好了&#xff1f;“机器是否会取代人类的工作”是当前讨论最多的话题之一。这主要源自于近几年以人工智能为代表的新技术的快速发展与商业化。尽管各研究机构的预测数据有所不同&#xff0c;但相同的…

冈萨雷斯《数字图像处理》读书笔记(十一)——表示和描述

虽然不是专门研究图像分割的&#xff08;峰兄才是&#xff09;&#xff0c;但多少接触了一点&#xff0c;并且图像分割是图像处理中的最为复杂的&#xff0c;通过图像分割可以很好地认识图像处理的好多方法。今天看的是边界追踪和链码的表示。网易计算机视觉工程师的第一道选择…

细胞内钾多钠少——原初生物的第三大遗迹?

来源&#xff1a;科学网在我们每日的饮食中&#xff0c;食盐&#xff08;氯化钠&#xff09;是少不了的&#xff0c;难以想象我们怎么能够每天吃完全没有盐味的食物。不仅人类如此&#xff0c;许多动物&#xff0c;例如食草的动物如牛和羊&#xff0c;也会主动寻找土表盐粒。我…

冈萨雷斯《数字图像处理》读书笔记(九)——形态学图像处理

形态学来自于生物学&#xff0c;研究动植物的形态和结构。运用在图像中可提取如边界、骨架和凸壳。初学形态学都是在二值化的图像上研究&#xff0c;之后可以扩展到灰度图像。 膨胀和腐蚀 数学形态学与集合论分不开&#xff0c;因为形态学中的操作是基于两个集合的&#xff0…

云计算行业现状及未来发展趋势

来源&#xff1a;国元证券、乐晴智库摘要&#xff1a;按照服务类型云计算被分为IaaS、PaaS、SaaS。▌云计算产业链构成按照服务类型云计算被分为IaaS、PaaS、SaaS。IaaS基础设施及服务:IaaS主要提供计算基础设施服务&#xff0c;主要包括CPU、内存、存储、网络、虚拟化软件、分…

冈萨雷斯《数字图像处理》读书笔记(三)——空间滤波

滤波这个词来源于频域处理&#xff0c;因为它的目的就是针对频率分量而言的&#xff0c;滤除一定的频率分量。但其实滤波在时域&#xff08;图像中对应为空域&#xff09;中也可以完成相应的操作&#xff0c;比如低通滤波器滤除了代表细节的高频分量&#xff0c;我们可以直接在…

WinInet:HTTPS 请求出现无效的证书颁发机构的处理

首先&#xff0c;微软提供的WinInet库封装了对网页访问的方法。 最近工作需要从https服务器获取数据&#xff0c;都知道https和http网页的访问方式不同&#xff0c;多了一道证书认证程序&#xff0c;这样就使得https在请求起来比http要复杂的多&#xff1b;好在&#xff0c;Win…

热度下的冷思考——智能眼镜到底有没有前途?

来源&#xff1a;环球网我们曾期望Google眼镜能够成为革命性的新产品&#xff0c;因为它某种程度上实现了大家对未来的幻想。然而Google眼镜作为概念产品虽然有趣&#xff0c;但它仍然太不成熟&#xff0c;而且因为存在侵犯隐私的可能还被大众抵触&#xff0c;更重要的是它花去…

TFRecords文件的存储与读取

将cats和dogs两个文件夹各1000张图片存储为&#xff1a;train.tfrecords#将图片文件生成train record import os import tensorflow as tf from PIL import Image #生成cats和dogs的record文件 path./data/train filenamesos.listdir(path) writertf.python_io.TFRecordWriter(…

对比激光SLAM与视觉SLAM:谁会成为未来主流趋势?

来源&#xff1a;智车科技摘要&#xff1a;SLAM&#xff08;同步定位与地图构建&#xff09;&#xff0c;是指运动物体根据传感器的信息&#xff0c;一边计算自身位置&#xff0c;一边构建环境地图的过程&#xff0c;解决机器人等在未知环境下运动时的定位与地图构建问题。目前…

链表中的指针

中期答辩改在了国庆之后&#xff0c;终于有时间可以看看剑指offer了。在看到单向链表的部分&#xff0c;对指针&#xff0c;尤其是头指针有点疑惑。首先容易理解的是链表的节点是一个结构体&#xff0c;该结构体包含一个数据&#xff08;一般是int型&#xff09;&#xff0c;还…

实现TFrecords文件的保存与读取

import os import cv2 import numpy as np import tensorflow as tf """ 将train文件夹下的cats和dog文件夹处理成train.tfrecords放在train文件夹里 """ #将图片的路径和对应的标签存储在list中返回 def deal(dir):images []temp []for root,…

工具推荐-css3渐变生成工具

今天工作用到了css3渐变&#xff0c;但是写起来才发现太麻烦了&#xff0c;而却很浪费时间&#xff0c;所以在这里向大家推荐一个在线的css3 渐变生成工具 地址是&#xff1a;http://www.colorzilla.com/gradient-editor/ 这个工具是可视化视图&#xff0c;用起来就和photoshop…

神经网络相关的笔试题目集合(一)

在找工作的过程中发现好多公司没有专门的、传统的图像处理岗位&#xff0c;所以只能参加算法类的笔试甚至AI类的笔试。在AI的笔试中几乎全是关于神经网络的问题&#xff0c;其实也都是很基础的一些问题&#xff0c;如果事先做了准备&#xff0c;可以从容应对。而对于我这种从传…

中美超算“你追我赶” 中国优势可圈可点

来源&#xff1a;新华网摘要&#xff1a;中美超算“你追我赶” 中国优势可圈可点新一期全球超级计算机&#xff15;&#xff10;&#xff10;强榜单&#xff11;&#xff12;日在美国达拉斯发布。与半年前的榜单相比&#xff0c;全球格局变化不大&#xff0c;美国在最快超算上…

吴恩达作业1:逻辑回归实现猫的分类

思路&#xff1a;输入样本X与随机初始权重W相乘&#xff0c;利用sigmoid激活函数输出值&#xff0c;对于二分类问题&#xff0c;用交叉熵损失函数来计算损失值&#xff0c;通过交叉熵损失函数利用链式法则求出W和b的偏导&#xff0c;梯度下降更新W和b即可&#xff0c;&#xff…