How to get a random number in specific range using Javascript? - javascript

I'm trying to find a way to run in my Node script command that gets a random number from 0.01 to 10.85 for example. The number must look like 0.01 and not like 0.000000001.
How can I do this?
My current command:
var randomTicket = helper.getRandomInt(0, 10.85);
That command for some reason it returns only the number 0
Are there any other alternative ways?

Math.random would do the trick. It returns a value between [0,1) (1 is exclusive). Then you scale the range by the difference between max and min and add min as offset.
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
But because you get a float value, you can not clip the decimal after the second position. You can format it to a string. I'm not sure but this should work.
var number = getRandomArbitrary(0.01, 10.85);
var numString = number.toFixed(2);
EDIT
If you only generate integers then multiply min and max by 100.0 and divide the result by 100.0.
var number = getRandomArbitrary(1.0, 1085.0);
var numString = (number / 100.0).toFixed(2);
or
var number = getRandomInt(1, 1085);
var numString = (number / 100.0).toFixed(2);

Related

Math random add subtract counter limited between a range of numbers [duplicate]

This question already has answers here:
Generating random whole numbers in JavaScript in a specific range
(40 answers)
Closed 2 years ago.
can you help me out on how to limit the below to stay within a min and max range eg 3 - 10
<div id="number">3</div>
setInterval(function(){
random = (Math.floor((Math.random()*1)+1));
var plusOrMinus = Math.random() < 0.5 ? -1 : 1;
random = random * plusOrMinus;
currentnumber = document.getElementById('number');
document.getElementById('number').innerHTML = parseInt(currentnumber.innerHTML) + random;
}, 1000);
See Mozilla Docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_two_values
Getting a random integer between two values This example returns a random integer between the specified values. The value is no lower
than min (or the next integer greater than min if min isn't an
integer), and is less than (but not equal to) max.
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive
}
By Mozilla Contributors, licensed under CC-BY-SA 2.5.

Order of operation and How does the random() play in this scenario

Just started learning loops and I'm having trouble understanding the order of operation here in the let value, along with how the random() works in this scenario.
From what it looks like: Math.floor() prevents decimals and Math.random() selects a random number between 0 and 36. Does random() select a random value for both MAX and MIN? Does random() also generate a random for its self to be multiplied by whatever the value of MAX and MIN equal after being subtracted, then adding the MIN back?
const MIN = 0;
const MAX = 36;
var testNumber = 15;
var i = 1;
while (MAX) {
let randomValue = Math.floor(Math.random() * (MAX - MIN)) + MIN;
if (randomValue == testNumber) {
break;
}
Math.random() provides a random floating point number between 0 and 1. If you want to get a wider range of random values, you multiply by the magnitude of the range you want (i.e. MAX - MIN). Then, if MIN is great than 0 you'll need to add it to the resulting random number, otherwise the results range would be 0 up to (MAX - MIN).
As you say, Math.floor() simply rounds the result down to the nearest integer.
The Math.floor() function returns the largest integer less than or equal to a given number. This is in contrast to the Math.ceil() function that returns the largest integer more than or equal to a given number.
The Math.random() function returns a floating-point, pseudo-random number in the range 0 to less than 1 (inclusive of 0, but not 1) with an approximately uniform distribution over that range — which you can then scale to your desired range.
So in the case of your randomValue variable, a pseudo-random value between the values for MIN and MAX is generated. This value could have decimals because of how Math.random() operates thus Math.floor is used to get a whole number. MIN is added to the end so that the random value will always fall within the range, especially if MIN is not 0.

How does the Javascript device that generate any random number between two number inclusive work mathematically?

Math.floor() rounds the decimal to "A number representing the largest integer less than or equal to the specified number." So Math.floor(45.03) will be 45 and Math.floor(-34.23) will be 35.
And Math.random generates a (decimal, or whole) number between 0, inclusive and 1 exclusive.
I just learned this:
Math.floor(Math.random()*(max-min+1)+min);
This will generate a random whole number between max and min inclusive. I can figure out mathematically why it works. Just wondering.
Lets call Math.random(), R; max M;min m. If you just look at the inside:
R*(M-m+1)+m //or RM-Rm+R+m,
It's obvious the quantity is at least as big as m. But why is it no bigger than M? I assume this works with negative M and m, as well.
Lets assume r is Math.random() which is a number between 0, inclusive and 1 exclusive; which we show it as:
// Let r is shortcut for Math.random()
r => [0 to 1} // lets [] symbols for inclusive and {} symbols for exclusive
to get a number in a larger scale, we can multiply it with N:
//scale by N:
r * N => [0 to N}
to include N in our range, we can use one number greater than N and round the result:
r * (N+1) => [ 0 to (N+1) }
floor(r * (N+1)) => [ 0 to N ] // decimals after N will be removed
So up to now, we reach a good formula: to have a random number between 0 and N (both inclusive), we should use: floor(r * (N+1))
if we shift the equation to start from a min value:
//add `min` to equation:
floor(r * (N+1)) + min => [ min to N+min ]
it is almost finished: consider N+min as max, we have:
N+min = max => N = max-min
replace it in our equation:
floor(r * (max-min+1)) + min => [ min to max ]
Note: It is obvious that we can move the min inside the floor function as it is an integer value and does not have any decimal digits. so we could write it also as:
floor( r * (max-min+1) + min )
It's pretty easy, but you need to write it down a little wordy:
var min = 10;
var max = 20;
var difference = max - min; // 10
var random = Math.random() // (0...1)
var randomDifference = random * difference; // (0...difference)
var withMinOffset = randomDifference + min; // (10...20)
The above withMinOffset is the random value between min and max. The reason this works is because you know the number cannot be lower than min, so we will always have to add the min to the randomised number. Then we know we want a range, so we can use max - min to get the maximum amount of randomness we can get.
The number will never be bigger than M simply because difference + min === max, which is the upper limit. Multiplying say, 10, by a random number between 0 and 1 will always generate a number between 0 and 10. Adding the min to it will always have a number between min and min + difference.

Random integer in a certain range excluding one number

I would like get a random number in a range excluding one number (e.g. from 1 to 1000 exclude 577). I searched for a solution, but never solved my issue.
I want something like:
Math.floor((Math.random() * 1000) + 1).exclude(577);
I would like to avoid for loops creating an array as much as possible, because the length is always different (sometimes 1 to 10000, sometimes 685 to 888555444, etc), and the process of generating it could take too much time.
I already tried:
Javascript - Generating Random numbers in a Range, excluding certain numbers
How can I generate a random number within a range but exclude some?
How could I achieve this?
The fastest way to obtain a random integer number in a certain range [a, b], excluding one value c, is to generate it between a and b-1, and then increment it by one if it's higher than or equal to c.
Here's a working function:
function randomExcluded(min, max, excluded) {
var n = Math.floor(Math.random() * (max-min) + min);
if (n >= excluded) n++;
return n;
}
This solution only has a complexity of O(1).
One possibility is not to add 1, and if that number comes out, you assign the last possible value.
For example:
var result = Math.floor((Math.random() * 100000));
if(result==577) result = 100000;
In this way, you will not need to re-launch the random method, but is repeated. And meets the objective of being a random.
As #ebyrob suggested, you can create a function that makes a mapping from a smaller set to the larger set with excluded values by adding 1 for each value that it is larger than or equal to:
// min - integer
// max - integer
// exclusions - array of integers
// - must contain unique integers between min & max
function RandomNumber(min, max, exclusions) {
// As #Fabian pointed out, sorting is necessary
// We use concat to avoid mutating the original array
// See: http://stackoverflow.com/questions/9592740/how-can-you-sort-an-array-without-mutating-the-original-array
var exclusionsSorted = exclusions.concat().sort(function(a, b) {
return a - b
});
var logicalMax = max - exclusionsSorted.length;
var randomNumber = Math.floor(Math.random() * (logicalMax - min + 1)) + min;
for(var i = 0; i < exclusionsSorted.length; i++) {
if (randomNumber >= exclusionsSorted[i]) {
randomNumber++;
}
}
return randomNumber;
}
Example Fiddle
Also, I think #JesusCuesta's answer provides a simpler mapping and is better.
Update: My original answer had many issues with it.
To expand on #Jesus Cuesta's answer:
function RandomNumber(min, max, exclusions) {
var hash = new Object();
for(var i = 0; i < exclusions.length; ++i ) { // TODO: run only once as setup
hash[exclusions[i]] = i + max - exclusions.length;
}
var randomNumber = Math.floor((Math.random() * (max - min - exclusions.length)) + min);
if (hash.hasOwnProperty(randomNumber)) {
randomNumber = hash[randomNumber];
}
return randomNumber;
}
Note: This only works if max - exclusions.length > maximum exclusion. So close.
You could just continue generating the number until you find it suits your needs:
function randomExcluded(start, end, excluded) {
var n = excluded
while (n == excluded)
n = Math.floor((Math.random() * (end-start+1) + start));
return n;
}
myRandom = randomExcluded(1, 10000, 577);
By the way this is not the best solution at all, look at my other answer for a better one!
Generate a random number and if it matches the excluded number then add another random number(-20 to 20)
var max = 99999, min = 1, exclude = 577;
var num = Math.floor(Math.random() * (max - min)) + min ;
while(num == exclude || num > max || num < min ) {
var rand = Math.random() > .5 ? -20 : 20 ;
num += Math.floor((Math.random() * (rand));
}
import random
def rng_generator():
a = random.randint(0, 100)
if a == 577:
rng_generator()
else:
print(a)
#main()
rng_generator()
Exclude the number from calculations:
function toggleRand() {
// demonstration code only.
// this algorithm does NOT produce random numbers.
// return `0` - `576` , `578` - `n`
return [Math.floor((Math.random() * 576) + 1)
,Math.floor(Math.random() * (100000 - 578) + 1)
]
// select "random" index
[Math.random() > .5 ? 0 : 1];
}
console.log(toggleRand());
Alternatively, use String.prototype.replace() with RegExp /^(577)$/ to match number that should be excluded from result; replace with another random number in range [0-99] utilizing new Date().getTime(), isNaN() and String.prototype.slice()
console.log(
+String(Math.floor(Math.random()*(578 - 575) + 575))
.replace(/^(577)$/,String(isNaN("$1")&&new Date().getTime()).slice(-2))
);
Could also use String.prototype.match() to filter results:
console.log(
+String(Math.floor(Math.random()*10))
.replace(/^(5)$/,String(isNaN("$1")&&new Date().getTime()).match(/[^5]/g).slice(-1)[0])
);

javascript: calculate x% of a number

I am wondering how in javascript if i was given a number (say 10000) and then was given a percentage (say 35.8%)
how would I work out how much that is (eg 3580)
var result = (35.8 / 100) * 10000;
(Thank you jball for this change of order of operations. I didn't consider it).
This is what I would do:
// num is your number
// amount is your percentage
function per(num, amount){
return num*amount/100;
}
...
<html goes here>
...
alert(per(10000, 35.8));
Your percentage divided by 100 (to get the percentage between 0 and 1) times by the number
35.8/100*10000
Best thing is to memorize balance equation in natural way.
Amount / Whole = Percentage / 100
usually You have one variable missing, in this case it is Amount
Amount / 10000 = 35.8 / 100
then you have high school math (proportion) to multiple outer from both sides and inner from both sides.
Amount * 100 = 358 000
Amount = 3580
It works the same in all languages and on paper. JavaScript is no exception.
I use two very useful JS functions:
http://blog.bassta.bg/2013/05/rangetopercent-and-percenttorange/
function rangeToPercent(number, min, max){
return ((number - min) / (max - min));
}
and
function percentToRange(percent, min, max) {
return((max - min) * percent + min);
}
If you want to pass the % as part of your function you should use the following alternative:
<script>
function fpercentStr(quantity, percentString)
{
var percent = new Number(percentString.replace("%", ""));
return fpercent(quantity, percent);
}
function fpercent(quantity, percent)
{
return quantity * percent / 100;
}
document.write("test 1: " + fpercent(10000, 35.873))
document.write("test 2: " + fpercentStr(10000, "35.873%"))
</script>
In order to fully avoid floating point issues, the amount whose percent is being calculated and the percent itself need to be converted to integers. Here's how I resolved this:
function calculatePercent(amount, percent) {
const amountDecimals = getNumberOfDecimals(amount);
const percentDecimals = getNumberOfDecimals(percent);
const amountAsInteger = Math.round(amount + `e${amountDecimals}`);
const percentAsInteger = Math.round(percent + `e${percentDecimals}`);
const precisionCorrection = `e-${amountDecimals + percentDecimals + 2}`; // add 2 to scale by an additional 100 since the percentage supplied is 100x the actual multiple (e.g. 35.8% is passed as 35.8, but as a proper multiple is 0.358)
return Number((amountAsInteger * percentAsInteger) + precisionCorrection);
}
function getNumberOfDecimals(number) {
const decimals = parseFloat(number).toString().split('.')[1];
if (decimals) {
return decimals.length;
}
return 0;
}
calculatePercent(20.05, 10); // 2.005
As you can see, I:
Count the number of decimals in both the amount and the percent
Convert both amount and percent to integers using exponential notation
Calculate the exponential notation needed to determine the proper end value
Calculate the end value
The usage of exponential notation was inspired by Jack Moore's blog post. I'm sure my syntax could be shorter, but I wanted to be as explicit as possible in my usage of variable names and explaining each step.
It may be a bit pedantic / redundant with its numeric casting, but here's a safe function to calculate percentage of a given number:
function getPerc(num, percent) {
return Number(num) - ((Number(percent) / 100) * Number(num));
}
// Usage: getPerc(10000, 25);
var number = 10000;
var result = .358 * number;
Harder Way (learning purpose) :
var number = 150
var percent= 10
var result = 0
for (var index = 0; index < number; index++) {
const calculate = index / number * 100
if (calculate == percent) result += index
}
return result

Categories