Поднимите 10 в степень в JavaScript, есть ли лучшие способы, чем это

Мне нужно создать целочисленное значение для определенной степени (это не правильный термин, но в основном мне нужно создать 10, 100, 1000 и т. Д.) "Мощность" будет указана в качестве параметра функции. Я придумала решение, но MAN чувствует, что это неправильно и неправильно. Я хотел бы узнать лучший способ, если есть один, может быть, тот, который не основан на строках? Кроме того, eval() не вариант.

Вот что у меня есть в это время:

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

    return parseFloat(numToParse);
}

Я также только что придумал это решение, не основанное на строках, но все еще кажется хакерским из-за цикла:

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

    return tmp;
}

Кстати, мне нужно было сделать это, чтобы создать метод округления для работы с валютой. Я использовал var отформатированный = Math.round(значение * 100) / 100

но этот код появлялся повсюду, и я хотел, чтобы метод позаботился о округлении с определенной точностью, поэтому я создал это

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

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

Думаю, я бы включил это сюда, поскольку это уже пригодилось.

7 ответов

Решение

В ES5 и более ранних версиях используйте Math.pow:

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

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

В ES2016 и более поздних версиях используйте оператор возведения в степень:

let result = 10 ** precision;

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

Почему бы и нет:

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

Это имеет тот же результат, что и ваша функция, но я до сих пор не понимаю приложения / намерения.

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

Если все, что вам нужно сделать, это поднять 10 на разные силы, или любую базу на любую силу, почему бы не использовать встроенный Math.pow(10,power); если у вас нет конкретных причин, чтобы изобрести велосипед

Для мощности в 10³³ и выше, Math.pow() может потерять точность Например:

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

Хотя это не повседневная проблема, с которой вы можете столкнуться в JavaScript, в некоторых ситуациях это может быть довольно проблематично, особенно с операторами сравнения. Одним из примеров является Google log10Floor() функция из библиотеки закрытия:

/**
 * 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;
};

Если вы передаете мощность 10 выше 10³³, эта функция может вернуть неверный результат, потому что Math.pow(10, 33) > 1e33 оценивает true, Я обошел это, используя приведение числа, конкатенируя показатель степени в '1e':

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

И, исправляя log10Floor() функция:

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;
};

Примечание: ошибка в библиотеке закрытия была исправлена.

Используйте таблицу поиска. Но если это для округления сумм в валюте, вы должны использовать BigDecimal вместо всей schemozzle.

Я просто наткнулся на что-то во время прохождения https://github.com/aecostas/huffman. Скомпилированный код (JS) имеет строку

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

Если вы попытаетесь оценить 9e9 (на консоли узла и браузера), вы получите 9000000000, что составляет "9*10^9". На основании этого вы можете просто сделать следующее, чтобы получить 10-ую степень. var n = 2; eval("1e"+n); //outputs 100

РЕДАКТИРОВАТЬ: Подробнее об экспоненциальной записи от http://www.2ality.com/2012/03/displaying-numbers.html.

В JavaScript используются две десятичные записи: Фиксированная запись [ "+" | "-" ] цифра + [ "." цифра + ] и экспоненциальная запись [ "+" | "-" ] цифра ["." цифра + ] "е" [ "+" | "-" ] цифра + Пример экспоненциального обозначения -1,37e+2. Для вывода перед точкой всегда ровно одна цифра, для ввода можно использовать более одной цифры. Экспоненциальная запись интерпретируется следующим образом: Дано число в экспоненциальной записи: значение и экспонента. Значение этого числа значимо и × 10степени. Следовательно, -1.37e+2 представляет число -137.

Другие вопросы по тегам