Raise 10 to a power in javascript, are there better ways than this

浪子不回头ぞ 提交于 2019-12-13 12:24:34

问题


I have a need to create an integer value to a specific power (that's not the correct term, but basically I need to create 10, 100, 1000, etc.) The "power" will be specified as a function parameter. I came up with a solution but MAN does it feel hacky and wrong. I'd like to learn a better way if there is one, maybe one that isn't string based? Also, eval() is not an option.

Here is what I have at this time:

function makeMultiplierBase(precision)
{
    var numToParse = '1';
    for(var i = 0; i < precision; i++)
    {
        numToParse += '0';
    }

    return parseFloat(numToParse);
}

I also just came up with this non-string based solution, but still seems hacky due to the loop:

function a(precision)
{
    var tmp = 10;
    for(var i = 1; i < precision; i++)
    {
        tmp *= 10;
    }

    return tmp;
}

BTW, I needed to do this to create a rounding method for working with currency. I had been using var formatted = Math.round(value * 100) / 100

but this code was showing up all over the place and I wanted to have a method take care of the rounding to a specific precision so I created this

if(!Math.roundToPrecision)
{
    Math.roundToPrecision = function(value, precision)
    {
        Guard.NotNull(value, 'value');

        b = Math.pow(10, precision);
        return Math.round(value * b) / b;
    }  
}

Thought I'd include this here as it's proven to be handy already.


回答1:


In ES5 and earlier, use Math.pow:

var result = Math.pow(10, precision);

var precision = 5;
var result = Math.pow(10, precision);
console.log(result);

In ES2016 and later, use the exponentiation operator:

let result = 10 ** precision;

let precision = 5;
let result = 10 ** precision;
console.log(result);



回答2:


Why not:

function precision(x) {  
  return Math.pow(10, x);
}



回答3:


if all you need to do is raise 10 to different powers, or any base to any power why not use the built in Math.pow(10,power); unless you have soe specific need to reason to reinvent the wheel




回答4:


This has the same result as your function, but i still don't understand the application/intention.

function makeMultiplierBase(precision,base){
    return Math.pow(base||10,precision);
}



回答5:


For powers at 10³³ and above, Math.pow() may lose precision. For example:

Math.pow(10, 33);    //-> 1.0000000000000001e+33
Math.pow(10, 34);    //-> 1.0000000000000001e+34
Math.pow(10, 35);    //-> 1e+35
Math.pow(10, 36);    //-> 1e+36
Math.pow(10, 37);    //-> 1.0000000000000001e+37

While not an everyday problem that you may run into in JavaScript, it could be quite troublesome in some situations, particularly with comparison operators. One example is Google's log10Floor() function from the Closure Library:

/**
 * Returns the precise value of floor(log10(num)).
 * Simpler implementations didn't work because of floating point rounding
 * errors. For example
 * <ul>
 * <li>Math.floor(Math.log(num) / Math.LN10) is off by one for num == 1e+3.
 * <li>Math.floor(Math.log(num) * Math.LOG10E) is off by one for num == 1e+15.
 * <li>Math.floor(Math.log10(num)) is off by one for num == 1e+15 - 1.
 * </ul>
 * @param {number} num A floating point number.
 * @return {number} Its logarithm to base 10 rounded down to the nearest
 *     integer if num > 0. -Infinity if num == 0. NaN if num < 0.
 */
goog.math.log10Floor = function(num) {
  if (num > 0) {
    var x = Math.round(Math.log(num) * Math.LOG10E);
    return x - (Math.pow(10, x) > num);
  }
  return num == 0 ? -Infinity : NaN;
};

If you pass a power of 10 above 10³³, this function could return an incorrect result because Math.pow(10, 33) > 1e33 evaluates to true. The way I worked around this is to use Number coercion, concatenating the exponent to '1e':

+'1e33'    //-> 1e+33
+'1e34'    //-> 1e+34
+'1e35'    //-> 1e+35
+'1e36'    //-> 1e+36
+'1e37'    //-> 1e+37

And, fixing the log10Floor() function:

goog.math.log10Floor = function(num) {
  if (num > 0) {
    var x = Math.round(Math.log(num) * Math.LOG10E);
    return x - (+('1e' + x) > num);
  }
  return num == 0 ? -Infinity : NaN;
};

Note: The bug in closure library has since been fixed.




回答6:


I just stumbled on something while going through https://github.com/aecostas/huffman. The compiled code(js) has a line

alphabet_next = sorted.slice(0, +(sorted.length - 1 - groupsize) + 1 || 9e9);

If you try to evaluate 9e9 (on the node and browser console) it gives you 9000000000 which is "9*10^9".Based on that you could simply do the below to get the 10th power. var n = 2; eval("1e"+n); //outputs 100

EDIT: More on exponential notation from http://www.2ality.com/2012/03/displaying-numbers.html.

There are two decimal notations used by JavaScript: Fixed notation [ "+" | "-" ] digit+ [ "." digit+ ] and exponential notation [ "+" | "-" ] digit [ "." digit+ ] "e" [ "+" | "-" ] digit+ An example of exponential notation is -1.37e+2. For output, there is always exactly one digit before the point, for input you can use more than one digit. Exponential notation is interpreted as follows: Given a number in exponential notation: significand e exponent. The value of that number is significand × 10exponent. Hence, -1.37e+2 represents the number −137.




回答7:


Use a lookup table. But if this is for rounding currency amounts, you should be using BigDecimal instead of the entire schemozzle.



来源:https://stackoverflow.com/questions/6286589/raise-10-to-a-power-in-javascript-are-there-better-ways-than-this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!