21

我需要创建一个特定幂的整数值(这不是正确的术语,但基本上我需要创建 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 formatted = Math.round(value * 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;
    }  
}

我想我会把它包括在这里,因为它已经被证明很方便。

4

7 回答 7

49

在 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);

于 2011-06-08T23:51:21.170 回答
3

为什么不:

function precision(x) {  
  return Math.pow(10, x);
}
于 2011-06-08T23:52:05.210 回答
3

这与您的功能具有相同的结果,但我仍然不了解应用程序/意图。

function makeMultiplierBase(precision,base){
    return Math.pow(base||10,precision);
}
于 2011-06-08T23:52:07.943 回答
3

如果您需要做的只是将 10 提升到不同的权力,或者任何权力的任何基础,为什么不使用内置的,Math.pow(10,power);除非您有特别需要重新发明轮子的理由

于 2011-06-08T23:54:00.737 回答
2

对于 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 中可能会遇到日常问题,但在某些情况下可能会非常麻烦,尤其是比较运算符。一个例子是log10Floor()来自 Closure Library 的 Google 函数:

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

注意:闭包库中的错误已被修复

于 2014-03-26T09:13:49.947 回答
0

我在浏览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 使用了两种十进制表示法: 固定表示法 [ "+" | "-" ] 数字+ [ "." digit+ ] 和指数符号 [ "+" | “-“ ] 数字 [ ”。” 数字+ ] "e" [ "+" | "-" ] digit+ 指数符号的一个例子是-1.37e+2。对于输出,点前始终只有一位数字,对于输入,您可以使用多个数字。指数表示法解释如下:给定一个指数表示法的数字: significand e exponent。该数字的值是 有效数× 10指数。因此,-1.37e+2 表示数字 -137。

于 2016-06-29T12:28:39.617 回答
-1

使用查找表。但如果这是为了四舍五入货币金额,您应该使用 BigDecimal 而不是整个 schemozzle。

于 2011-10-18T01:55:51.180 回答