The problem of a parseInt function found by javascript random number

A few days ago, I wanted to forge some data and used random numbers. I didn't write it myself, so I searched the Internet and found this article: https://www.cnblogs.com/starof/p/4988516.html  . Then I tested it and found a problem about parseInt. Finally, we found that the reason for the problem was that we didn't know enough about this method. Let's talk about the specific process in detail.

The random number method in the above connection is as follows (with some test code added):

  

var temp=randomNum(0,0); in this way, the method in the link is called. According to the logic in the method, it should always return 0. Why does it contain other numbers The following is a step-by-step test.

1. I modified the above method first. The effect I want is that 0-2 parameters can be passed in, and the parameters are of different sizes:

//    Get random number test 1
var getRangeRandomNumberTest1 = function(num1,num2){ 
    num1 = num1 === undefined ? 0: num1;
    num2 = num2 === undefined ? 0: num2;
    var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
    return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10);  
}; 
var tempRandomNumbers1=[];
for(var i=0;i<=100000000;i++){
    var temp=getRangeRandomNumberTest1();
    if(tempRandomNumbers1.indexOf(temp)<0){
        tempRandomNumbers1.push(temp);
    }
}
console.log("Random number group length:"+tempRandomNumbers1.length);
console.log("Contents of random number array:"+JSON.stringify(tempRandomNumbers1));

Take a look at the test results:

  

There was no accident in the result, just like the one above.

2. I want to see if the returned result is not 0 when I call in this way. Here is test 2:

//    Get random number test 2
var getRangeRandomNumberTest2 = function(num1,num2){ 
    num1 = num1 === undefined ? 0: num1;
    num2 = num2 === undefined ? 0: num2;
    var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
    var temp1=Math.random();
    var temp2=parseInt(temp1*(maxNum-minNum+1)+minNum,10);
    var temp3="Maximum:"+maxNum+";Minimum:"+minNum+";Random number:"+temp1;
    if(temp2!==0){
        console.log(temp3);
    }
    return temp2;  
}; 

var tempRandomNumbers2=[];
for(var i=0;i<=100000000;i++){
    var temp=getRangeRandomNumberTest2();
    if(tempRandomNumbers2.indexOf(temp)<0){
        tempRandomNumbers2.push(temp);
    }
}
console.log("Random number group length:"+tempRandomNumbers2.length);
console.log("Contents of random number array:"+JSON.stringify(tempRandomNumbers2));

Also look at the test results:

  

console.log(parseInt(6.467984137170646e-7));    //A random number generated above   //Output: 6 

Some problems are found here. When the return result is not 0, the generated random numbers are very small. Then, check the definition and syntax of parseInt function

//Definition
parseInt() Function to parse a string and return an integer.
//grammar
parseInt(string, radix)

The first parameter of parseInt function is string. The process of executing parseInt(6.467984137170646e-7) should be to convert 6.467984137170646e-7 into a string first

6.467984137170646e-7.toString()                    //Output results:"6.467984137170646e-7"
0.0000006467984137170646.toString()                //Output results:"6.467984137170646e-7"
6.467984137170646e-7===0.0000006467984137170646    //Output results: true

At this point, the result will come to the surface. In the number 6.467984137170646e-7, "e" has a specific meaning. But "6.467984137170646e-7" is a string, in which "e" has no special meaning and cannot represent the power of 10, which is no different from other characters.

parseInt("0.0000006467984137170646")            //Output result: 0    //This result is what we want

See the result, now the problem should be the conversion of 0.0000006467984137170646 to string

0.00000654321.toString()                        //Output results:"0.00000654321"
0.000000654321.toString()                        //Output results:"6.54321e-7"
0.0000000654321.toString()                        //Output results:"6.54321e-8"

  

Here's the problem. The random number generated by Math.random() is very small (when there is a continuous > = 6 zeros after the decimal point), which will be represented by scientific counting method

Since there is a problem with this call (although it's an unconventional call), I want to get the random number in another way.

3. The next way to get random numbers:

//    Get random number test 3
var getRangeRandomNumberTest3 = function(num1,num2){ 
    num1 = num1 === undefined ? 0: num1;
    num2 = num2 === undefined ? 0: num2;
    var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
    return Math.floor(Math.random() * (maxNum - minNum)) + minNum;
}; 
var tempRandomNumbers3=[];
for(var i=0;i<=10000;i++){
    var temp=getRangeRandomNumberTest3(9);
    if(tempRandomNumbers3.indexOf(temp)<0){
        tempRandomNumbers3.push(temp);
    }
}
console.log("Random number group length:"+tempRandomNumbers3.length);
console.log("Contents of random number array:"+JSON.stringify(tempRandomNumbers3));

Take a look at the test results:

  

This test, getRangeRandomNumberTest3(9), is called in this way. It is intended to generate a random number of 0-9. There is a lack of 9, which should be the problem of Math.floor. It's changing

4. Another way to get random numbers:

//    Get random number test 4
var getRangeRandomNumberTest4 = function(num1,num2){ 
    num1 = num1 === undefined ? 0: num1;
    num2 = num2 === undefined ? 0: num2;
    var minNum=Math.min(num1,num2),maxNum=Math.max(num1,num2);
    return Math.round(Math.random() * (maxNum - minNum)) + minNum;
}; 
var tempRandomNumbers4=[];
for(var i=0;i<=100000000;i++){
    var temp=getRangeRandomNumberTest4(9);
    if(tempRandomNumbers4.indexOf(temp)<0){
        tempRandomNumbers4.push(temp);
    }
}
console.log("Random number group length:"+tempRandomNumbers4.length);
console.log("Contents of random number array:"+JSON.stringify(tempRandomNumbers4));

Take a look at the test results:

  

The result is very satisfactory this time, and the desired result has been achieved As the final version, the method is further improved:

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

Let's take a look at the test screenshot of the final version:

  

So far, this note is over, thank you!

Tags: Javascript JSON

Posted on Mon, 04 Nov 2019 22:41:58 -0500 by moboter