前几天想伪造一些数据,用到了随机数,没有自己写,便在网上找了一下,找到了这篇文章:https://www.cnblogs.com/starof/p/4988516.html 。之后测试了一下,发现了一个关于parseInt的问题。最后发现造成问题的原因是对该方法不够了解,下面详细说一下具体的过程。

  上文中连接中的随机数方法是这样的(并添加一些测试代码):

  

  var temp=randomNum(0,0); 这样调用链接中的方法,按照方法中的逻辑应该永远返回0才对,为什么还包含其他的数字……下面是一步一步的测试。

  一、我先修改了一下上面的方法,我想要的效果是可以传入0-2个参数,并且参数大小不分先后:

  1. // 获取随机数测试1
  2. var getRangeRandomNumberTest1 = function(num1,num2){
  3. num1 = num1 === undefined ? 0: num1;
  4. num2 = num2 === undefined ? 0: num2;
  5. var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
  6. return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10);
  7. };
  8. var tempRandomNumbers1=[];
  9. for(var i=0;i<=100000000;i++){
  10. var temp=getRangeRandomNumberTest1();
  11. if(tempRandomNumbers1.indexOf(temp)<0){
  12. tempRandomNumbers1.push(temp);
  13. }
  14. }
  15. console.log("随机数数组长度:"+tempRandomNumbers1.length);
  16. console.log("随机数数组内容:"+JSON.stringify(tempRandomNumbers1));

  看一下测试结果:

  

  这次结果没有什么意外,和上面的一样。

  二、我想看一下,用这种方式调用,什么条件下返回结果不为0,下面是测试2:

  1. // 获取随机数测试2
  2. var getRangeRandomNumberTest2 = function(num1,num2){
  3. num1 = num1 === undefined ? 0: num1;
  4. num2 = num2 === undefined ? 0: num2;
  5. var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
  6. var temp1=Math.random();
  7. var temp2=parseInt(temp1*(maxNum-minNum+1)+minNum,10);
  8. var temp3="最大值:"+maxNum+";最小值:"+minNum+";随机数:"+temp1;
  9. if(temp2!==0){
  10. console.log(temp3);
  11. }
  12. return temp2;
  13. };
  14.  
  15. var tempRandomNumbers2=[];
  16. for(var i=0;i<=100000000;i++){
  17. var temp=getRangeRandomNumberTest2();
  18. if(tempRandomNumbers2.indexOf(temp)<0){
  19. tempRandomNumbers2.push(temp);
  20. }
  21. }
  22. console.log("随机数数组长度:"+tempRandomNumbers2.length);
  23. console.log("随机数数组内容:"+JSON.stringify(tempRandomNumbers2));

  同样再看一下测试结果:

  

  1. console.log(parseInt(6.467984137170646e-7)); //上面生成的一个随机数 //输出结果:6

  这里发现了一些问题,返回结果不为0的时候,生成的随机数都特别小;之后查了一下parseInt函数的定义和语法

  1. //定义
  2. parseInt() 函数可解析一个字符串,并返回一个整数。
  3. //语法
  4. parseInt(string, radix)

  parseInt函数的第一个参数是字符串,那执行parseInt(6.467984137170646e-7)的过程应该是先将6.467984137170646e-7转成一个字符串

  1. 6.467984137170646e-7.toString() //输出结果:"6.467984137170646e-7"
  2. 0.0000006467984137170646.toString() //输出结果:"6.467984137170646e-7"
  3. 6.467984137170646e-7===0.0000006467984137170646 //输出结果:true

  这时结果就要浮出水面了。在数字中6.467984137170646e-7,"e"有特定的含义。但是"6.467984137170646e-7"就是一个字符串,其中"e"没有什么特殊含义,不能表示10的几次幂,和其他的字符没有什么区别。

  1. parseInt("0.0000006467984137170646") //输出结果:0 //这个结果是我们想要的结果

  看到结果,现在问题应该是0.0000006467984137170646转为字符串的问题了

  1. 0.00000654321.toString() //输出结果:"0.00000654321"
  2. 0.000000654321.toString() //输出结果:"6.54321e-7"
  3. 0.0000000654321.toString() //输出结果:"6.54321e-8"

  

  问题就在这里,Math.random()生成的随机数特别小时(小数点后面有连续的>=6个0时),这个小数会用科学计数法表示……

  既然这样调用有问题(虽然是非常规调用),我想在换一种方式获取随机数。

  三、下一种获取随机数的方法:

  1. // 获取随机数测试3
  2. var getRangeRandomNumberTest3 = function(num1,num2){
  3. num1 = num1 === undefined ? 0: num1;
  4. num2 = num2 === undefined ? 0: num2;
  5. var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
  6. return Math.floor(Math.random() * (maxNum - minNum)) + minNum;
  7. };
  8. var tempRandomNumbers3=[];
  9. for(var i=0;i<=10000;i++){
  10. var temp=getRangeRandomNumberTest3(9);
  11. if(tempRandomNumbers3.indexOf(temp)<0){
  12. tempRandomNumbers3.push(temp);
  13. }
  14. }
  15. console.log("随机数数组长度:"+tempRandomNumbers3.length);
  16. console.log("随机数数组内容:"+JSON.stringify(tempRandomNumbers3));

  看一下测试结果:

  

  这次测试,getRangeRandomNumberTest3(9),是这样调用的,本意想生成0-9的随机数,这里缺少了9,应该是Math.floor的问题,那就在换一个……

  四、再换一种获取随机数的方法:

  1. // 获取随机数测试4
  2. var getRangeRandomNumberTest4 = function(num1,num2){
  3. num1 = num1 === undefined ? 0: num1;
  4. num2 = num2 === undefined ? 0: num2;
  5. var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
  6. return Math.round(Math.random() * (maxNum - minNum)) + minNum;
  7. };
  8. var tempRandomNumbers4=[];
  9. for(var i=0;i<=100000000;i++){
  10. var temp=getRangeRandomNumberTest4(9);
  11. if(tempRandomNumbers4.indexOf(temp)<0){
  12. tempRandomNumbers4.push(temp);
  13. }
  14. }
  15. console.log("随机数数组长度:"+tempRandomNumbers4.length);
  16. console.log("随机数数组内容:"+JSON.stringify(tempRandomNumbers4));

  再看一下测试结果:

  

  这次结果很是满意,达到了想要的结果……作为最终版,再将方法完善一下:

  1. var getRangeRandomNumber = function(num1,num2){
  2. num1 = Number.isInteger(num1) ? num1: 0;
  3. num2 = Number.isInteger(num2) ? num2: 0;
  4. var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
  5. return Math.round(Math.random() * (maxNum - minNum)) + minNum;
  6. };

  下面看一下最终版的测试截图:

  

  至此,这篇笔记就结束了,谢谢大家!

javascript随机数发现的一个parseInt函数的问题的更多相关文章

  1. Javascript 随机数函数 学习之二:产生服从正态分布随机数

    一.为什么需要服从正态分布的随机函数 一般我们经常使用的随机数函数 Math.random() 产生的是服从均匀分布的随机数,能够模拟等概率出现的情况,例如 扔一个骰子,1到6点的概率应该相等,但现实 ...

  2. javascript使用parseInt函数时需要注意的一些问题

    这个问题大家可能会忽视,我在项目中就遇到了.写了提醒一下大家!!! 在用javascript的parseInt函数时,parseInt("08")或者parseInt(" ...

  3. 字串符相关 split() 字串符分隔 substring() 提取字符串 substr()提取指定数目的字符 parseInt() 函数可解析一个字符串,并返回一个整数。

    split() 方法将字符串分割为字符串数组,并返回此数组. stringObject.split(separator,limit) 我们将按照不同的方式来分割字符串: 使用指定符号分割字符串,代码如 ...

  4. Javascript 随机数函数 学习之一:产生服从均匀分布随机数

    大家都知道Math.random是 javascript 中返回伪随机数的函数,但查看 MDN, The Math.random() function returns a floating-point ...

  5. 给你一个能生成1到5随机数的函数,用它写一个函数生成1到7的随机数。 (即,使用函数rand5()来实现函数rand7())

    给你一个能生成1到5随机数的函数,用它写一个函数生成1到7的随机数. (即,使用函数rand5()来实现函数rand7()). 解答 rand5可以随机生成1,2,3,4,5:rand7可以随机生成1 ...

  6. JavaScript的parseint()函数

    定义和用法 parseInt() 函数可解析一个字符串,并返回一个整数. 语法 parseInt(string, radix) 参数 描述 string 必选项.要转换为数字的字符串. radix 可 ...

  7. JavaScript parseInt() 函数

    定义和用法 parseInt() 函数可解析一个字符串,并返回一个整数. 语法 parseInt(string, radix) 参数 描述 string 必需.要被解析的字符串. radix 可选.表 ...

  8. 在javascript中:(函数()()是一个匿名函数

    在javascript中:(函数()()是一个匿名函数,它主要使用函数中的变量范围来避免全局变量,影响整个页面环境,并提高代码兼容性. (函数())是标准函数定义,但不会复制到任何变量.所以有一个没有 ...

  9. JS函数 编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数。

    编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数. 任务 第一步: 编写代码完成一个函数的定义吧. 第二步: 我们来补充函数体中的控制语句,完成函数功能吧. 提示: ...

随机推荐

  1. unordered_map / HashTable 的负载因子是什么意思

    // in C++ 前段时间在看一些关于这个的文章时遇到了一些问题:unordered_map / HashTable 的负载因子是什么意思 经过度娘的搜索,最后得出: 若设 Hash 表的桶数量为 ...

  2. Linux-(1)Linux概述

    一.概述 1.1 Linux的历史 操作系统,英语Operating System简称为OS.说道操作系统就需要先讲一讲Unix,UNIX操作系统,是一个强大的多用户.多任务操作系统, 支持多种处理器 ...

  3. Python3 函数实践之简易购物系统

    函数实践之简易购物系统 项目主要需求: 用户可以自行选择功能 该购物系统具有注册/登录/购物/购物车/退出登录功能 用户在登录后才能使用购物/购物车/退出登录功能 ''' 注册 登录 购物 购物车 退 ...

  4. 从零开始入门 K8s | etcd 性能优化实践

    作者 | 陈星宇(宇慕)  阿里云基础技术中台技术专家 本文整理自<CNCF x Alibaba 云原生技术公开课>第 17 讲. 导读:etcd 是容器云平台用于存储关键元信息的组件.阿 ...

  5. Orleans 初接触(二) 测试用例

    [返回导航] 在简单了解了Orleans 之后我们可以通过几个例子去加深印象 一.快速入门示例 这个例子也是跟着<Microsoft Orleans 之 入门指南>(https://www ...

  6. 在Linux系统下制作系统启动盘(Ubuntu Linux)

    在Linux系统下制作系统启动盘有两种方法: 1.用dd命令 2.用Linux自带的图形界面工具 Startup Disk Creator 本教程使用第2种方式,用Linux自带的图形界面工具制作系统 ...

  7. .NET 中数据访问用的 DBHelper(Sql Server) 类

    public class DBHelper { private static string DBConnectString = "Data Source=.;Initial Catalog= ...

  8. 1.1 Spring 概述

    1.1 Spring 概述 1.1.1 Spring 的简史 第一阶段:xml配置 Spring 1.x时代使用xml配置Bean 第二阶段:注解配置 Spring2.x  Spring 提供了声明B ...

  9. 【Springboot】用Springboot Admin监控你的微服务应用

    1 简介 目前,微服务大行其道,各大小公司争相学习模仿,把单体应用拆得七零八落.服务多了,运行的实例多了,给运维人员的压力就更大了.如果有十几个应用,单单做Health Check就已经够费时间的了. ...

  10. 02-EF Core笔记之保存数据

    EF Core通过ChangeTracker跟踪需要写入数据库的更改,当需要保存数据时,调用DbContext的SaveChanges方法完成保存. 基本的添加.更新.删除操作示例如下: using ...