Random Number Complete Function (v3)

Revision 3 of this benchmark created on


Setup

function isNumber(num){
    return (typeof num === 'number' && !isNaN(num));
}

function toFixed(value,precision, roundingMethod = 'round') 
{
    roundingMethod = roundingMethod.toLowerCase()

    if(isNaN(precision)){
        throw new Error("precision is NaN");
    }
    if(isNaN(value)){
        throw new Error("value is NaN");
    }
    if(precision<0) precision = 0

    let negative = (value<0);
    
    value = Math.abs(value);
    
    let fixer = Math.pow(10,precision);

    if(roundingMethod == 'floor')  value = Math.floor(value * fixer) / fixer; 
    else if(roundingMethod == 'ceil')  value = Math.ceil(value * fixer) / fixer;
    else  value = Math.round(value * fixer) / fixer;

    return (negative ? (-value) : value);
}

function findPrecision(num) {
    if (!isFinite(num)) return 0;
    if (typeof num !== "number") num = +num; 
    if (isNaN(num)) return 0;

    num = Math.abs(num);
    if(num < 1e-16) return 16.5;
    let numFix = toFixed(num,16,'floor')

    let e = 1, decP = 0;
    while (Math.round(num * e) / e !== num) { e *= 10; decP++; }
    e = 1; let decPFix = 0;
    while (Math.round(numFix * e) / e !== numFix) { e *= 10; decPFix++; }

    return (decP > decPFix ? decPFix : decP);
}

function randNum(min,max, precision = true)
{
    if(isNaN(min) || isNaN(max))
    {
        throw new Error("min or max is NaN");
    }
    if(min == max)  return max;

    if(precision === true){
        let minP = findPrecision(min)
        let maxP = findPrecision(max)
        if(minP==16.5) minP = 16;
        if(maxP==16.5) maxP = 16;
        precision = maxP > minP ? maxP : minP;

        return toFixed(((Math.random() * ((max+1)-min)) + min), precision);
    }

    if(isNumber(precision)){
        return toFixed(((Math.random() * ((max+1)-min)) + min), precision);
    }
    else{
        return ((Math.random() * ((max+1)-min)) + min);
    }
}

let opts = [
  [1, 2, 2],
  [0, 12, false],
  [-8, 4, true],
  [-1.34, 2.945, true],
  [-20, -5, null],
  [2.8, 0, 2],
  [1.4858, 6.45, true],
  [9.857203, 8.857203, 3],
  [-2.3455, 2.3455, true],
  [3.89, 3.456, 1],
  [0, 0, true]
]

Test runner

Ready to run.

Testing in
TestOps/sec
"Complex" rand num
for(let i = 0, b=0; i < opts.length; ++i){
	b = randNum(...opts[i])
}
ready
Normal rand num
let min,max;
for(let i = 0, b=0; i < opts.length; ++i){
	min = opts[i][0]; max = opts[i][1];
	b = ((Math.random() * ((max+1)-min)) + min)
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.