获得10的幂的最快方法

Fastest way to obtain a power of 10

我将在此处使用 Java 作为示例,因为它可能完全是特定于语言的,但我通常对执行此操作的方法很感兴趣。
当然,最简单明了的方法是这样的:

Math.pow(10, x)

但据我所知,电源是一项相当昂贵的操作。因此我认为应该有更好的方法,因为它看起来很明显 - 我只需要在 1!

之后有 x 个零

编辑: 是的,这可能是过早的优化。上下文是四舍五入到小数点后n位,常用的是这样的:

private final static int[] powersOf10 = {1, 10, 100, 1000, 10000};
public static double round(double number, int decimals) {
    if(decimals < 5)
        return Math.rint(number / powersOf10[decimals]) * powersOf10[decimals];
    double c = Math.pow(10, decimals);
    return Math.rint(number * c) / c;
}

这是我当前使用的舍入函数,如您所见,我已经对最常用的值使用了查找 table,但我仍然很好奇是否有一些位魔术或类似的东西改进这个。

最快的方法是

static final int[] POWERS_OF_10 = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
static int powerOfTen(int pow) {
  return POWERS_OF_10[pow];
}

...因为没有更高的 10 次方符合 int。对不起,如果你期待更酷的东西。

这是我的解决方案:

double number = 7893.147895673;
int dp = 7;

String pattern = ".";
for (int i = 1; i <= dp; i++) {
    pattern += "#";
}//for (int i = 1; i <= dp; i++)

DecimalFormat df = new DecimalFormat (pattern);
System.out.println(df.format(number));

对此我很满意,我三天前开始学习 Java,我很喜欢!

这个问题很老了,但对于通过搜索登陆这里的人来说,我希望这有用。

我使用 JMH 测试了三种方法的性能:

  1. Math.pow(10, exponent)
  2. 根据已接受的答案在数组中查找
  3. 在硬编码的 switch 语句中查找。

这是 JMH 基准代码:

private static final long[] POWERS_OF_TEN = {
                       10L,
                      100L,
                    1_000L,
                   10_000L,
                  100_000L,
                1_000_000L,
               10_000_000L,
              100_000_000L,
            1_000_000_000L,
           10_000_000_000L,
          100_000_000_000L,
        1_000_000_000_000L,
       10_000_000_000_000L,
      100_000_000_000_000L,
    1_000_000_000_000_000L};

int exponent;

@Setup(Level.Iteration) public void randomExponent()
{
    exponent = RAND.nextInt(16);
}

@Benchmark public long mathPow()
{
    return (long) Math.pow(10, exponent);
}

@Benchmark public long arrayLookup()
{
    return POWERS_OF_TEN[exponent];
}

@Benchmark public long switchLookup()
{
    switch (exponent)
    {
        case 1:  { return                    10L; }
        case 2:  { return                   100L; }
        case 3:  { return                 1_000L; }
        case 4:  { return                10_000L; }
        case 5:  { return               100_000L; }
        case 6:  { return             1_000_000L; }
        case 7:  { return            10_000_000L; }
        case 8:  { return           100_000_000L; }
        case 9:  { return         1_000_000_000L; }
        case 10: { return        10_000_000_000L; }
        case 11: { return       100_000_000_000L; }
        case 12: { return     1_000_000_000_000L; }
        case 13: { return    10_000_000_000_000L; }
        case 14: { return   100_000_000_000_000L; }
        case 15: { return 1_000_000_000_000_000L; }
    }
    return 0L;
}

并且(鼓声......)这是结果:

Benchmark                           Mode  Cnt    Score    Error   Units
PowerOfTenBenchmark.mathPow        thrpt   15   24.134 ± 32.132  ops/us
PowerOfTenBenchmark.arrayLookup    thrpt   15  515.684 ± 10.056  ops/us
PowerOfTenBenchmark.switchLookup   thrpt   15  461.318 ±  4.941  ops/us

所以#2 数组查找是最快的,确认接受的答案是正确的。

如果您认为 POWERS_OF_TEN 数组字面值初始化器很丑陋(我同意),还有一种更短且可能更不容易出错的方法:

private static final long[] POWERS_OF_TEN = IntStream.range(0, 16)
    .mapToLong(i -> (long) Math.pow(10, i)).toArray();