How can I generate numbers that range from 000 to 999? Also, a single digit can only occur maximum of two times in the same number.
Examples of numbers I'd like to generate:
094
359
188
900
004
550
Examples of numbers I don't want to generate:
000
999
444
What I've got so far:
function randomNumbers () {
var one = Math.floor(Math.random() * 9) + 0;
var two = Math.floor(Math.random() * 9) + 0;
var three = Math.floor(Math.random() * 9) + 0;
return '' + one + two + three;
};
I know the code can be improved a lot, I just don't know how. Current function isn't checking if the same number occurs three times (should only occur a maximum of two).
I can use jQuery in the project.
Here is a solution that will never have to retry. It returns the result in constant time and spreads the probability evenly among the allowed numbers:
function randomNumbers () {
var val = Math.floor(Math.random() * 990);
val += Math.floor((val+110)/110);
return ('000' + val).substr(-3);
};
// Test it:
var count = new Array(1000).fill(0);
for (i=0; i<100000; i++) {
count[+randomNumbers()]++;
}
// filter out the counters that remained zero:
count = count.map((v,i) => [i,v]).filter( ([i,v]) => !v ).map( ([i,v]) => i );
console.log('numbers that have not been generated: ', count);
You could count the digits and check before return the value.
function getRandom() {
var count = {};
return [10, 10, 10].map(function (a) {
var v;
do {
v = Math.floor(Math.random() * a);
} while (count[v] && count[v] > 1)
count[v] = (count[v] || 0) + 1;
return v;
}).join('');
}
var i = 1000;
while (i--) {
console.log(getRandom());
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
Try this :
$(document).ready(function() {
for(var i=0; i<50;i++)
console.log(randomNumbers ());
function randomNumbers () {
var one = Math.floor(Math.random() * 9);
var two = Math.floor(Math.random() * 9);
var three = Math.floor(Math.random() * 9);
if( one == two && two == three && one == three )
randomNumbers();
else
return (""+one + two + three);
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
The following should give you the expected result:
function getRandom() {
var randomNo = Math.floor(Math.random() * 999);
var splitted = randomNo.toString().split("");
var res = [];
splitted.filter(v => {
res.push(v);
if (res.filter(x => x == v).length > 2) return false;
return true;
});
while (splitted.length < 3) {
var ran = Math.floor(Math.random() * 9);
if (splitted.indexOf(ran) < 0) splitted.push(ran);
}
console.log(splitted.join(""))
return splitted.join("");
}
for (x = 0; x<100;x++) {getRandom()}
Keeps track of what you started.
function randomNumbers () {
var one = Math.floor(Math.random() * 10);
var two = Math.floor(Math.random() * 10);
var three = Math.floor(Math.random() * 10);
return one==two && two==three ? randomNumbers(): '' + one + two + three;
};
Here the function call itself recursively up to the point where it result
meets the requirements. The probability of generating three equal numbres is 1/100 so be sure that it will recurse nearly to never.
If, it were me, to be more flexible, I'd write a function I could pass parameters to and have it generate the numbers like the below:
function getRandoms(min, max, places, dupes, needed) {
/**
* Gets an array of random numbers with rules applied
* #param min int min Minimum digit allowed
* #param mas int min Maximum digit allowed
* #param dupes int Maximum duplicate digits to allow
* #param int needed The number of values to return
* #return array Array of random numbers
*/
var vals = [];
while (vals.length < needed) {
var randomNum = Math.floor(Math.random() * max) + min;
var digits = randomNum.toString().split('');
while (digits.length < places) {
digits.push(0);
}
var uniqueDigits = digits.removeDupes();
if ((places - uniqueDigits.length) <= dupes) vals.push(digits.join(''));
}
return vals;
}
// for convenience
Array.prototype.removeDupes = function() {
/**
* Removes duplicate from an array and returns the modified array
* #param array this The original array
* #return array The modified array
*/
var unique = [];
$.each(this, function(i, item) {
if ($.inArray(item, unique)===-1) unique.push(item);
});
return unique;
}
var randomNumbers = getRandoms(0, 999, 3, 2, 10);
console.log(randomNumbers);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Suppose I have a value of 15.7784514, I want to display it 15.77 with no rounding.
var num = parseFloat(15.7784514);
document.write(num.toFixed(1)+"<br />");
document.write(num.toFixed(2)+"<br />");
document.write(num.toFixed(3)+"<br />");
document.write(num.toFixed(10));
Results in -
15.8
15.78
15.778
15.7784514000
How do I display 15.77?
Convert the number into a string, match the number up to the second decimal place:
function calc(theform) {
var num = theform.original.value, rounded = theform.rounded
var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
rounded.value = with2Decimals
}
<form onsubmit="return calc(this)">
Original number: <input name="original" type="text" onkeyup="calc(form)" onchange="calc(form)" />
<br />"Rounded" number: <input name="rounded" type="text" placeholder="readonly" readonly>
</form>
The toFixed method fails in some cases unlike toString, so be very careful with it.
Update 5 Nov 2016
New answer, always accurate
function toFixed(num, fixed) {
var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?');
return num.toString().match(re)[0];
}
As floating point math in javascript will always have edge cases, the previous solution will be accurate most of the time which is not good enough.
There are some solutions to this like num.toPrecision, BigDecimal.js, and accounting.js.
Yet, I believe that merely parsing the string will be the simplest and always accurate.
Basing the update on the well written regex from the accepted answer by #Gumbo, this new toFixed function will always work as expected.
Old answer, not always accurate.
Roll your own toFixed function:
function toFixed(num, fixed) {
fixed = fixed || 0;
fixed = Math.pow(10, fixed);
return Math.floor(num * fixed) / fixed;
}
Another single-line solution :
number = Math.trunc(number*100)/100
I used 100 because you want to truncate to the second digit, but a more flexible solution would be :
number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits)
where digits is the amount of decimal digits to keep.
See Math.trunc specs for details and browser compatibility.
I opted to write this instead to manually remove the remainder with strings so I don't have to deal with the math issues that come with numbers:
num = num.toString(); //If it's not already a String
num = num.slice(0, (num.indexOf("."))+3); //With 3 exposing the hundredths place
Number(num); //If you need it back as a Number
This will give you "15.77" with num = 15.7784514;
Update (Jan 2021)
Depending on its range, a number in javascript may be shown in scientific notation. For example, if you type 0.0000001 in the console, you may see it as 1e-7, whereas 0.000001 appears unchanged (0.000001).
If your application works on a range of numbers for which scientific notation is not involved, you can just ignore this update and use the original answer below.
This update is about adding a function that checks if the number is in scientific format and, if so, converts it into decimal format. Here I'm proposing this one, but you can use any other function that achieves the same goal, according to your application's needs:
function toFixed(x) {
if (Math.abs(x) < 1.0) {
let e = parseInt(x.toString().split('e-')[1]);
if (e) {
x *= Math.pow(10,e-1);
x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
}
} else {
let e = parseInt(x.toString().split('+')[1]);
if (e > 20) {
e -= 20;
x /= Math.pow(10,e);
x += (new Array(e+1)).join('0');
}
}
return x;
}
Now just apply that function to the parameter (that's the only change with respect to the original answer):
function toFixedTrunc(x, n) {
x = toFixed(x)
// From here on the code is the same than the original answer
const v = (typeof x === 'string' ? x : x.toString()).split('.');
if (n <= 0) return v[0];
let f = v[1] || '';
if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
while (f.length < n) f += '0';
return `${v[0]}.${f}`
}
This updated version addresses also a case mentioned in a comment:
toFixedTrunc(0.000000199, 2) => "0.00"
Again, choose what fits your application needs at best.
Original answer (October 2017)
General solution to truncate (no rounding) a number to the n-th decimal digit and convert it to a string with exactly n decimal digits, for any n≥0.
function toFixedTrunc(x, n) {
const v = (typeof x === 'string' ? x : x.toString()).split('.');
if (n <= 0) return v[0];
let f = v[1] || '';
if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
while (f.length < n) f += '0';
return `${v[0]}.${f}`
}
where x can be either a number (which gets converted into a string) or a string.
Here are some tests for n=2 (including the one requested by OP):
0 => 0.00
0.01 => 0.01
0.5839 => 0.58
0.999 => 0.99
1.01 => 1.01
2 => 2.00
2.551 => 2.55
2.99999 => 2.99
4.27 => 4.27
15.7784514 => 15.77
123.5999 => 123.59
And for some other values of n:
15.001097 => 15.0010 (n=4)
0.000003298 => 0.0000032 (n=7)
0.000003298257899 => 0.000003298257 (n=12)
parseInt is faster then Math.floor
function floorFigure(figure, decimals){
if (!decimals) decimals = 2;
var d = Math.pow(10,decimals);
return (parseInt(figure*d)/d).toFixed(decimals);
};
floorFigure(123.5999) => "123.59"
floorFigure(123.5999, 3) => "123.599"
num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)
This will return 19.66
Simple do this
number = parseInt(number * 100)/100;
Just truncate the digits:
function truncDigits(inputNumber, digits) {
const fact = 10 ** digits;
return Math.floor(inputNumber * fact) / fact;
}
This is not a safe alternative, as many others commented examples with numbers that turn into exponential notation, that scenery is not covered by this function
// typescript
// function formatLimitDecimals(value: number, decimals: number): number {
function formatLimitDecimals(value, decimals) {
const stringValue = value.toString();
if(stringValue.includes('e')) {
// TODO: remove exponential notation
throw 'invald number';
} else {
const [integerPart, decimalPart] = stringValue.split('.');
if(decimalPart) {
return +[integerPart, decimalPart.slice(0, decimals)].join('.')
} else {
return integerPart;
}
}
}
console.log(formatLimitDecimals(4.156, 2)); // 4.15
console.log(formatLimitDecimals(4.156, 8)); // 4.156
console.log(formatLimitDecimals(4.156, 0)); // 4
console.log(formatLimitDecimals(0, 4)); // 0
// not covered
console.log(formatLimitDecimals(0.000000199, 2)); // 0.00
These solutions do work, but to me seem unnecessarily complicated. I personally like to use the modulus operator to obtain the remainder of a division operation, and remove that. Assuming that num = 15.7784514:
num-=num%.01;
This is equivalent to saying num = num - (num % .01).
I fixed using following simple way-
var num = 15.7784514;
Math.floor(num*100)/100;
Results will be 15.77
My version for positive numbers:
function toFixed_norounding(n,p)
{
var result = n.toFixed(p);
return result <= n ? result: (result - Math.pow(0.1,p)).toFixed(p);
}
Fast, pretty, obvious. (version for positive numbers)
The answers here didn't help me, it kept rounding up or giving me the wrong decimal.
my solution converts your decimal to a string, extracts the characters and then returns the whole thing as a number.
function Dec2(num) {
num = String(num);
if(num.indexOf('.') !== -1) {
var numarr = num.split(".");
if (numarr.length == 1) {
return Number(num);
}
else {
return Number(numarr[0]+"."+numarr[1].charAt(0)+numarr[1].charAt(1));
}
}
else {
return Number(num);
}
}
Dec2(99); // 99
Dec2(99.9999999); // 99.99
Dec2(99.35154); // 99.35
Dec2(99.8); // 99.8
Dec2(10265.985475); // 10265.98
The following code works very good for me:
num.toString().match(/.\*\\..{0,2}|.\*/)[0];
This worked well for me. I hope it will fix your issues too.
function toFixedNumber(number) {
const spitedValues = String(number.toLocaleString()).split('.');
let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
decimalValue = decimalValue.concat('00').substr(0,2);
return '$'+spitedValues[0] + '.' + decimalValue;
}
// 5.56789 ----> $5.56
// 0.342 ----> $0.34
// -10.3484534 ----> $-10.34
// 600 ----> $600.00
function convertNumber(){
var result = toFixedNumber(document.getElementById("valueText").value);
document.getElementById("resultText").value = result;
}
function toFixedNumber(number) {
const spitedValues = String(number.toLocaleString()).split('.');
let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
decimalValue = decimalValue.concat('00').substr(0,2);
return '$'+spitedValues[0] + '.' + decimalValue;
}
<div>
<input type="text" id="valueText" placeholder="Input value here..">
<br>
<button onclick="convertNumber()" >Convert</button>
<br><hr>
<input type="text" id="resultText" placeholder="result" readonly="true">
</div>
An Easy way to do it is the next but is necessary ensure that the amount parameter is given as a string.
function truncate(amountAsString, decimals = 2){
var dotIndex = amountAsString.indexOf('.');
var toTruncate = dotIndex !== -1 && ( amountAsString.length > dotIndex + decimals + 1);
var approach = Math.pow(10, decimals);
var amountToTruncate = toTruncate ? amountAsString.slice(0, dotIndex + decimals +1) : amountAsString;
return toTruncate
? Math.floor(parseFloat(amountToTruncate) * approach ) / approach
: parseFloat(amountAsString);
}
console.log(truncate("7.99999")); //OUTPUT ==> 7.99
console.log(truncate("7.99999", 3)); //OUTPUT ==> 7.999
console.log(truncate("12.799999999999999")); //OUTPUT ==> 7.99
Here you are. An answer that shows yet another way to solve the problem:
// For the sake of simplicity, here is a complete function:
function truncate(numToBeTruncated, numOfDecimals) {
var theNumber = numToBeTruncated.toString();
var pointIndex = theNumber.indexOf('.');
return +(theNumber.slice(0, pointIndex > -1 ? ++numOfDecimals + pointIndex : undefined));
}
Note the use of + before the final expression. That is to convert our truncated, sliced string back to number type.
Hope it helps!
truncate without zeroes
function toTrunc(value,n){
return Math.floor(value*Math.pow(10,n))/(Math.pow(10,n));
}
or
function toTrunc(value,n){
x=(value.toString()+".0").split(".");
return parseFloat(x[0]+"."+x[1].substr(0,n));
}
test:
toTrunc(17.4532,2) //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1) //1.4
toTrunc(.4,2) //0.4
truncate with zeroes
function toTruncFixed(value,n){
return toTrunc(value,n).toFixed(n);
}
test:
toTrunc(17.4532,2) //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1) //1.4
toTrunc(.4,2) //0.40
If you exactly wanted to truncate to 2 digits of precision, you can go with a simple logic:
function myFunction(number) {
var roundedNumber = number.toFixed(2);
if (roundedNumber > number)
{
roundedNumber = roundedNumber - 0.01;
}
return roundedNumber;
}
I used (num-0.05).toFixed(1) to get the second decimal floored.
It's more reliable to get two floating points without rounding.
Reference Answer
var number = 10.5859;
var fixed2FloatPoints = parseInt(number * 100) / 100;
console.log(fixed2FloatPoints);
Thank You !
My solution in typescript (can easily be ported to JS):
/**
* Returns the price with correct precision as a string
*
* #param price The price in decimal to be formatted.
* #param decimalPlaces The number of decimal places to use
* #return string The price in Decimal formatting.
*/
type toDecimal = (price: number, decimalPlaces?: number) => string;
const toDecimalOdds: toDecimal = (
price: number,
decimalPlaces: number = 2,
): string => {
const priceString: string = price.toString();
const pointIndex: number = priceString.indexOf('.');
// Return the integer part if decimalPlaces is 0
if (decimalPlaces === 0) {
return priceString.substr(0, pointIndex);
}
// Return value with 0s appended after decimal if the price is an integer
if (pointIndex === -1) {
const padZeroString: string = '0'.repeat(decimalPlaces);
return `${priceString}.${padZeroString}`;
}
// If numbers after decimal are less than decimalPlaces, append with 0s
const padZeroLen: number = priceString.length - pointIndex - 1;
if (padZeroLen > 0 && padZeroLen < decimalPlaces) {
const padZeroString: string = '0'.repeat(padZeroLen);
return `${priceString}${padZeroString}`;
}
return priceString.substr(0, pointIndex + decimalPlaces + 1);
};
Test cases:
expect(filters.toDecimalOdds(3.14159)).toBe('3.14');
expect(filters.toDecimalOdds(3.14159, 2)).toBe('3.14');
expect(filters.toDecimalOdds(3.14159, 0)).toBe('3');
expect(filters.toDecimalOdds(3.14159, 10)).toBe('3.1415900000');
expect(filters.toDecimalOdds(8.2)).toBe('8.20');
Any improvements?
Another solution, that truncates and round:
function round (number, decimals, truncate) {
if (truncate) {
number = number.toFixed(decimals + 1);
return parseFloat(number.slice(0, -1));
}
var n = Math.pow(10.0, decimals);
return Math.round(number * n) / n;
};
function limitDecimalsWithoutRounding(val, decimals){
let parts = val.toString().split(".");
return parseFloat(parts[0] + "." + parts[1].substring(0, decimals));
}
var num = parseFloat(15.7784514);
var new_num = limitDecimalsWithoutRounding(num, 2);
Roll your own toFixed function: for positive values Math.floor works fine.
function toFixed(num, fixed) {
fixed = fixed || 0;
fixed = Math.pow(10, fixed);
return Math.floor(num * fixed) / fixed;
}
For negative values Math.floor is round of the values. So you can use Math.ceil instead.
Example,
Math.ceil(-15.778665 * 10000) / 10000 = -15.7786
Math.floor(-15.778665 * 10000) / 10000 = -15.7787 // wrong.
Gumbo's second solution, with the regular expression, does work but is slow because of the regular expression. Gumbo's first solution fails in certain situations due to imprecision in floating points numbers. See the JSFiddle for a demonstration and a benchmark. The second solution takes about 1636 nanoseconds per call on my current system, Intel Core i5-2500 CPU at 3.30 GHz.
The solution I've written involves adding a small compensation to take care of floating point imprecision. It is basically instantaneous, i.e. on the order of nanoseconds. I clocked 2 nanoseconds per call but the JavaScript timers are not very precise or granular. Here is the JS Fiddle and the code.
function toFixedWithoutRounding (value, precision)
{
var factorError = Math.pow(10, 14);
var factorTruncate = Math.pow(10, 14 - precision);
var factorDecimal = Math.pow(10, precision);
return Math.floor(Math.floor(value * factorError + 1) / factorTruncate) / factorDecimal;
}
var values = [1.1299999999, 1.13, 1.139999999, 1.14, 1.14000000001, 1.13 * 100];
for (var i = 0; i < values.length; i++)
{
var value = values[i];
console.log(value + " --> " + toFixedWithoutRounding(value, 2));
}
for (var i = 0; i < values.length; i++)
{
var value = values[i];
console.log(value + " --> " + toFixedWithoutRounding(value, 4));
}
console.log("type of result is " + typeof toFixedWithoutRounding(1.13 * 100 / 100, 2));
// Benchmark
var value = 1.13 * 100;
var startTime = new Date();
var numRun = 1000000;
var nanosecondsPerMilliseconds = 1000000;
for (var run = 0; run < numRun; run++)
toFixedWithoutRounding(value, 2);
var endTime = new Date();
var timeDiffNs = nanosecondsPerMilliseconds * (endTime - startTime);
var timePerCallNs = timeDiffNs / numRun;
console.log("Time per call (nanoseconds): " + timePerCallNs);
Building on David D's answer:
function NumberFormat(num,n) {
var num = (arguments[0] != null) ? arguments[0] : 0;
var n = (arguments[1] != null) ? arguments[1] : 2;
if(num > 0){
num = String(num);
if(num.indexOf('.') !== -1) {
var numarr = num.split(".");
if (numarr.length > 1) {
if(n > 0){
var temp = numarr[0] + ".";
for(var i = 0; i < n; i++){
if(i < numarr[1].length){
temp += numarr[1].charAt(i);
}
}
num = Number(temp);
}
}
}
}
return Number(num);
}
console.log('NumberFormat(123.85,2)',NumberFormat(123.85,2));
console.log('NumberFormat(123.851,2)',NumberFormat(123.851,2));
console.log('NumberFormat(0.85,2)',NumberFormat(0.85,2));
console.log('NumberFormat(0.851,2)',NumberFormat(0.851,2));
console.log('NumberFormat(0.85156,2)',NumberFormat(0.85156,2));
console.log('NumberFormat(0.85156,4)',NumberFormat(0.85156,4));
console.log('NumberFormat(0.85156,8)',NumberFormat(0.85156,8));
console.log('NumberFormat(".85156",2)',NumberFormat(".85156",2));
console.log('NumberFormat("0.85156",2)',NumberFormat("0.85156",2));
console.log('NumberFormat("1005.85156",2)',NumberFormat("1005.85156",2));
console.log('NumberFormat("0",2)',NumberFormat("0",2));
console.log('NumberFormat("",2)',NumberFormat("",2));
console.log('NumberFormat(85156,8)',NumberFormat(85156,8));
console.log('NumberFormat("85156",2)',NumberFormat("85156",2));
console.log('NumberFormat("85156.",2)',NumberFormat("85156.",2));
// NumberFormat(123.85,2) 123.85
// NumberFormat(123.851,2) 123.85
// NumberFormat(0.85,2) 0.85
// NumberFormat(0.851,2) 0.85
// NumberFormat(0.85156,2) 0.85
// NumberFormat(0.85156,4) 0.8515
// NumberFormat(0.85156,8) 0.85156
// NumberFormat(".85156",2) 0.85
// NumberFormat("0.85156",2) 0.85
// NumberFormat("1005.85156",2) 1005.85
// NumberFormat("0",2) 0
// NumberFormat("",2) 0
// NumberFormat(85156,8) 85156
// NumberFormat("85156",2) 85156
// NumberFormat("85156.",2) 85156
Already there are some suitable answer with regular expression and arithmetic calculation, you can also try this
function myFunction() {
var str = 12.234556;
str = str.toString().split('.');
var res = str[1].slice(0, 2);
document.getElementById("demo").innerHTML = str[0]+'.'+res;
}
// output: 12.23
Here is what is did it with string
export function withoutRange(number) {
const str = String(number);
const dotPosition = str.indexOf('.');
if (dotPosition > 0) {
const length = str.substring().length;
const end = length > 3 ? 3 : length;
return str.substring(0, dotPosition + end);
}
return str;
}
I'm generating a random number with the code below:
Math.floor((Math.random() * 9999) * 7);
Some of the results I'm getting:
45130,
2611,
34509,
36658
How would I get results like this(with 2 letters included):
TT45130,
PO2611,
KL34509,
GH36658
Side question:
What is the range of numbers that Math.random() carries? Can I set a specific range of values? Not necessary to answer but just curious.
You can use a function like below to get a random uppercase character:
function getRandomUppercaseChar() {
var r = Math.floor(Math.random() * 26);
return String.fromCharCode(65 + r);
}
So to generate a code as you specified with a two-letter prefix:
function generateCode() {
var prefix = new Array(2).fill().map(() => getRandomUppercaseChar()).join(""),
integer = Math.floor((Math.random() * 9999) * 7);
return prefix + integer;
}
NOTE: The above generateCode function uses modern ES6 and ES5 javascript, which is perfectly fine in a modern environment (such as Node.js or a current browser). However, if you wanted greater compatibility (for example, to ensure that it works in old browsers), you could rewrite it like so:
function generateCode() {
var integer = Math.floor((Math.random() * 9999) * 7);
for (var i = 0, prefix = ""; i < 2; ++i)
prefix += getRandomUppercaseChar();
return prefix + integer;
}
Try the simpler answer
var randomNumber = function () {
return Math.floor((Math.random() * 9999) * 7);
}
var randomChar = function () {
return String.fromCharCode(64 + Math.floor((Math.random() * 26)+1));
}
console.log(randomChar()+randomChar()+randomNumber());
//Sample outputs
HB10527 DR25496 IJ12394
Or you can use Number#toString for this purpose with radix = 36.
function getRChar() {
return (Math.random() * 26 + 10 | 0).toString(36).toUpperCase();
}
var s = getRChar() + getRChar() + Math.floor((Math.random() * 9999) * 7);
document.write(s);
If you need to generate a random string with JS, the most common way is to define an alphabet and pick random indices from that:
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var numbers = "0123456789";
var randomString = "";
// Pick two random chars
for (var i = 0; i < 2; i++) {
var rand = Math.floor(Math.random()*alphabet.length);
randomString = randomString + alphabet.charAt(rand);
}
// Pick four random digits
for (var i = 0; i < 4; i++) {
var rand = Math.floor(Math.random()*numbers.length);
randomString = randomString + numbers.charAt(rand);
}
// randomString now contains the string you want
Sample strings:
OJ8225
YL5053
BD7911
ES0159
You could use String.fromCharCode() with a random integer between 65 and 90 to get an uppercase letter, i.e.
String.fromCharCode(Math.random() * 26 + 65) + String.fromCharCode(Math.random() * 26 + 65) + Math.floor((Math.random() * 9999) * 7);
gives med the results: "SH21248", "BY42401", "TD35918".
If you want to guarantee that the string always has the same length, you could also use
String.fromCharCode(Math.random() * 26 + 65) + String.fromCharCode(Math.random() * 26 + 65) + Math.floor(Math.random() * 59993 + 10000);
Math.random() always returns a number between 0 and 1, but never 0 or 1 exactly.
An array of the alphabet, a random number is generated to get a random letter, repeated to get a second random letter and then joined to the random number generated as in your code:
var alphabet=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
var ranletter1 = alphabet[Math.floor(Math.random() * alphabet.length)];
var ranletter2 = alphabet[Math.floor(Math.random() * alphabet.length)];
var ranNum = Math.floor((Math.random() * 9999) * 7);
var ranCode = ranletter1 + ranletter2+ ranNum;
I am trying to execute below code:
var a = Math.floor(100000 + Math.random() * 900000);
a = a.substring(-2);
I am getting error like undefined is not a function at line 2, but when I try to do alert(a), it has something. What is wrong here?
That's because a is a number, not a string. What you probably want to do is something like this:
var val = Math.floor(1000 + Math.random() * 9000);
console.log(val);
Math.random() will generate a floating point number in the range [0, 1) (this is not a typo, it is standard mathematical notation to show that 1 is excluded from the range).
Multiplying by 9000 results in a range of [0, 9000).
Adding 1000 results in a range of [1000, 10000).
Flooring chops off the decimal value to give you an integer. Note that it does not round.
General Case
If you want to generate an integer in the range [x, y), you can use the following code:
Math.floor(x + (y - x) * Math.random());
This will generate 4-digit random number (0000-9999) using substring:
var seq = (Math.floor(Math.random() * 10000) + 10000).toString().substring(1);
console.log(seq);
I adapted Balajis to make it immutable and functional.
Because this doesn't use math you can use alphanumeric, emojis, very long pins etc
const getRandomPin = (chars, len)=>[...Array(len)].map(
(i)=>chars[Math.floor(Math.random()*chars.length)]
).join('');
//use it like this
getRandomPin('0123456789',4);
$( document ).ready(function() {
var a = Math.floor(100000 + Math.random() * 900000);
a = String(a);
a = a.substring(0,4);
alert( "valor:" +a );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
Your a is a number. To be able to use the substring function, it has to be a string first, try
var a = (Math.floor(100000 + Math.random() * 900000)).toString();
a = a.substring(-2);
You can get 4-digit this way .substring(startIndex, length), which would be in your case .substring(0, 4). To be able to use .substring() you will need to convert a to string by using .toString(). At the end, you can convert the resulting output into integer by using parseInt :
var a = Math.floor(100000 + Math.random() * 900000)
a = a.toString().substring(0, 4);
a = parseInt(a);
alert(a);
https://jsfiddle.net/v7dswkjf/
The problem is that a is a number. You cannot apply substring to a number so you have to convert the number to a string and then apply the function.
DEMO: https://jsfiddle.net/L0dba54m/
var a = Math.floor(100000 + Math.random() * 900000);
a = a.toString();
a = a.substring(-2);
$(document).ready(function() {
var a = Math.floor((Math.random() * 9999) + 999);
a = String(a);
a = a.substring(0, 4);
});
// It Will Generate Random 5 digit Number & Char
const char = '1234567890abcdefghijklmnopqrstuvwxyz'; //Random Generate Every Time From This Given Char
const length = 5;
let randomvalue = '';
for ( let i = 0; i < length; i++) {
const value = Math.floor(Math.random() * char.length);
randomvalue += char.substring(value, value + 1).toUpperCase();
}
console.log(randomvalue);
function getPin() {
let pin = Math.round(Math.random() * 10000);
let pinStr = pin + '';
// make sure that number is 4 digit
if (pinStr.length == 4) {
return pinStr;
} else {
return getPin();
}
}
let number = getPin();
Just pass Length of to number that need to be generated
await this.randomInteger(4);
async randomInteger(number) {
let length = parseInt(number);
let string:string = number.toString();
let min = 1* parseInt( string.padEnd(length,"0") ) ;
let max = parseInt( string.padEnd(length,"9") );
return Math.floor(
Math.random() * (max - min + 1) + min
)
}
I've created this function where you can defined the size of the OTP(One Time Password):
generateOtp = function (size) {
const zeros = '0'.repeat(size - 1);
const x = parseFloat('1' + zeros);
const y = parseFloat('9' + zeros);
const confirmationCode = String(Math.floor(x + Math.random() * y));
return confirmationCode;
}
How to use:
generateOtp(4)
generateOtp(5)
To avoid overflow, you can validate the size parameter to your case.
Numbers don't have substring method. For example:
let txt = "123456"; // Works, Cause that's a string.
let num = 123456; // Won't Work, Cause that's a number..
// let res = txt.substring(0, 3); // Works: 123
let res = num.substring(0, 3); // Throws Uncaught TypeError.
console.log(res); // Error
For Generating random 4 digit number, you can utilize Math.random()
For Example:
let randNum = (1000 + Math.random() * 9000).toFixed(0);
console.log(randNum);
This is quite simple
const arr = ["one", "Two", "Three"]
const randomNum = arr[Math.floor(Math.random() * arr.length)];
export const createOtp = (): number => {
Number(Math.floor(1000 + Math.random() * 9000).toString());
}