简体   繁体   English

可以使用Math.Pow(10,n)吗?

[英]Is it OK to use Math.Pow (10, n)?

I need to compute power (10, n) 我需要计算功率(10,n)

Is it OK to use Math.Pow (10, n) ? 可以使用Math.Pow (10, n)吗?

Or should I use a loop? 或者我应该使用循环?

for (int i = 0; i < n; i++){
  x*=10;
}

Which one is better? 哪一个更好? and why? 为什么?

Math.Pow is better. Math.Pow更好。
Here's a rule of thumb - in 99% of the scenarios, favor built-in functions over custom implementations. 这是一个经验法则 - 在99%的场景中,支持内置函数而不是自定义实现。 This makes your code clearer, saves you lots of work, and reduce chances for errors. 这使您的代码更清晰,节省了大量工作,并减少了出错的机会。

Only when you think of using built-in functions in ways they weren't meant to be used, or when they have severe latency problems (never encountered these scenarios myself, to be honest), should you consider building your own implementation. 只有当您考虑使用内置函数时,它们才不会被使用,或者当它们存在严重的延迟问题时(从未遇到过这些情况,说实话),您是否应该考虑构建自己的实现。

If both base and exponent are integers you might consider not using Pow. 如果base和exponent都是整数,则可以考虑不使用Pow。 But even in that case Pow is usually better because its more readable. 但即使在那种情况下,Pow通常更好,因为它更具可读性。 If at least one is a floatingpoint value, use Pow. 如果至少有一个是浮点值,请使用Pow。

If the exponent is 0.5 you should use Sqrt, and if the exponent is a small integer (2,3,4) expressing the formula with multiplications is faster, but less readable. 如果指数为0.5,则应使用Sqrt,如果指数为小整数(2,3,4),则表示具有乘法的公式更快,但可读性更低。

If you want to implement fast exponentiation with an integer exponent the Square-and-Multiply algorithm and not a simple loop might be what you want. 如果你想用整数指数实现快速求幂,那么Square-and-Multiply算法而不是简单的循环可能就是你想要的。 But in most scenarios Pow is still faster. 但在大多数情况下,Pow仍然更快。

For integers, maybe a for loop is faster than Math.Pow which probably deals with floating-point numbers. 对于整数,也许for循环比Math.Pow更快,它可能处理浮点数。 But I seriously doubt that the difference is significant in your case (even though I do not know it). 但我严重怀疑你的情况有多大差异(尽管我不知道)。

But if you work with 32-bit signed integers, then you can only store the values of 10^n for n <= 9. But then you would gain speed (and maybe readability) by storing these nine (ten) powers of ten in an array. 但是如果你使用32位有符号整数,那么你只能为n <= 9存储10 ^ n的值。但是你可以通过将这九个(十)个幂存储在10中来获得速度(也许是可读性)数组。 This is not hard: they are (1), 10, 100, 1000, ... . 这并不难:它们是(1),10,100,1000,....

If you need to compute 10^n for larger n, you do need to use floating-point numbers. 如果需要为较大的n计算10 ^ n,则需要使用浮点数。 And then there is no reason whatsoever not to use Math.Pow . 然后没有任何理由不使用Math.Pow This is as fast as it gets, and easily readable. 这是最快的,并且易于阅读。

Depends on which one communicates "10 to the power of n" more clearly. 取决于哪一个更清楚地传达“10的权力”。

In my case, Math.Pow(10, n) (although it could mean math, collectively, punching 10 and n in their faces as well, I dunno). 在我的例子中, Math.Pow(10, n) (尽管它可能意味着数学,也可以在他们的脸上冲击 10和n,我不知道)。

It's similar to how I'd rather algebraically express "10 to the power of n" as 10^n (or 10 n ) than 10 * 10 * 10 * ... * 10 n times , especially given that n is variable. 它类似于我更代数地将“10的幂与n”表示为10^n (或10 n )而不是10 * 10 * 10 * ... * 10 n times ,特别是考虑到n是可变的。

The answer would normally be yes, use Math.Pow(). 答案通常是肯定的,使用Math.Pow()。

However: if this code is really time-critical and you know you're dealing with small powers 1-9 so the result can be expressed in an Int32 then it can be worth optimizing. 但是:如果这段代码真的是时间关键的,并且你知道你正在处理小功率1-9,那么结果可以在Int32中表示,那么值得优化。 I just made a quick test-app and profiled the two versions (making sure the compiler hadn't optimized any code away) and the result on my laptop for the worst-case of 10^9 was that the loop was 20 times faster than Math.Pow(10,9). 我刚刚制作了一个快速的测试应用程序,并对这两个版本进行了分析(确保编译器没有优化任何代码),并且我的笔记本电脑上的最坏情况为10 ^ 9的结果是循环速度快20倍。 Math.Pow(10,9)。

But please remember, maybe this calculation is not really a bottleneck after all. 但请记住,也许这个计算毕竟不是瓶颈。 If you know for a fact that it is, eg if you've profiled your app and found it to be a real problem, then go ahead and replace it with a loop-based method (or even better, an array-lookup). 如果您知道它是一个事实,例如,如果您已经分析了您的应用程序并发现它是一个真正的问题,那么继续使用基于循环的方法替换它(或者更好的是,数组查找)。 If you're merely guessing that it may a problem then I would suggest you stick to Math.Pow. 如果你只是猜测它可能有问题,那么我建议你坚持使用Math.Pow。 In general: only optimize code that you know is a performance bottleneck. 通常:只优化您知道的性能瓶颈。

Math.Pow is provided for you, and well documented. Math.Pow是为您提供的,并且有详细记录。

Any gotchas are in the documentation. 任何陷阱是文档。

Why would you not want to use a provided function? 为什么你希望使用所提供的功能?

There are way more performant implementations of integer Pow, than multiplying by 10 in a loop. 有更多高性能Pow的实现方式,而不是在循环中乘以10。

See this answer , for example, it also works for other base values, not just 10. 例如,请参阅此答案 ,它也适用于其他基本值,而不仅仅是10。

Also, consider caching results, up until a reasonable amount, in an array. 另外,请考虑在数组中缓存结果,直到合理的数量。

Here's my recent code, for a reference: 这是我最近的代码,供参考:

private static readonly Int64[] PowBase10Cache = {
    1,
    10,
    100,
    1000,
    10000,
    100000,
    1000000,
    10000000,
    100000000,
    1000000000,
    10000000000,
    100000000000,
    1000000000000,
    10000000000000,
    100000000000000,
    1000000000000000,
    10000000000000000,
    100000000000000000,
    1000000000000000000,
    };

public static Int64 IPowBase10(int exp)
{
    return exp < PowBase10Cache.Length ? PowBase10Cache[exp] : IPow(10L, exp);
}

public static Int64 IPow(Int64 baseVal, int exp)
{
    Int64 result = 1;
    while (exp > 0)
    {
        if ((exp & 1) != 0)
        {
            result *= baseVal;
        }
        exp >>= 1;
        baseVal *= baseVal;
    }
    return result;
}

是的,可以使用Math.Pow()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM