如何编写一个计算功率的循环? [英] How to write a loop that calculates power?

查看:59
本文介绍了如何编写一个计算功率的循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个无需使用pow()函数即可计算功率的循环.我被困在如何做到这一点上.使用 base * = base 甚至可以将功率提高到4,所以有些东西似乎很奇怪,我似乎无法弄清楚.

I'm trying to write a loop that calculates power without using the pow() function. I'm stuck on how to do that. Doing base *= base works for even powers upto 4, so there is something totally weird that I can't seem to figure out.

int Fast_Power(int base, int exp){
    int i = 2;
    int result;

    if(exp == 0){
        result = 1;
        }
    if(exp == 1){
        result = base;
        }
    else{
        for(i = 2; i < exp; i++){
            base *= base; 
            result = base;
        }
    }
    return result;
}

推荐答案

base *= base;

您的问题出在该语句上,您根本不应该更改 base .相反,您应该基于 base 的常量值调整 result .

Your problem lies with that statement, you should not be changing base at all. Rather, you should be adjusting result based on the constant value of base.

要执行幂运算,您需要重复进行乘法,但是 base * = base 会为您提供重复的 squaring 值,并且因此,它将获得比期望值大得多的值.这实际上适用于四次幂,因为您迭代 4-2 次,对每个迭代进行平方,然后 x 4 ==(x 2 ) 2 .

To do powers, you need repeated multiplication, but the base *= base gives you a repeated squaring of the value and you'll therefore get a much bigger value than desired. This actually works for powers of four since you iterate 4 - 2 times, squaring each iteration, and x4 == (x2)2.

由于您迭代 6-2 次和 x 6 !=(<((x 2 ) 2 ) 2 ) 2 .后一个值实际上等于 x 16 .

It will not work for higher powers like six since you iterate 6 - 2 times, and x6 != (((x2)2)2)2. That latter value is actually equivalent to x16.

顺便说一句(尽管有您的争论),实际上保证可以使用2的幂.如果在这种情况下遵循代码,将会看到 result 从未分配值,因此返回值将是任意的.如果它对您有用,那是偶然的,并且可能会在某个时候咬住您.

As an aside (despite your contention), it's actually not guaranteed to work for powers of two. If you follow the code in that case, you'll see that result is never assigned a value so the return value will be arbitrary. If it's working for you, that's accidental and likely to bite you at some point.


您可以使用的算法应类似于:


The algorithm you can use should be something like:

float power(float base, int exponent):
    # 0^0 is undefined.

    if base == 0 and exponent == 0:
        throw bad_input

    # Handle negative exponents.

    if exponent < 0:
        return 1 / power(base, -exponent)

    # Repeated multiplication to get power.

    float result = 1
    while exponent > 0:
        # Use checks to detect overflow.

        float oldResult = result
        result *= base
        if result / base is not close to oldResult:
            throw overflow
        exponent -= 1

    return result

此算法处理:

  • 负整数指数(因为 x -y = 1 / x y );
  • 0 0 的未定义情况;和
  • 溢出(如果没有任意精度值)(基本上,如果(x * y)/y!= x ,则可以肯定地确定发生了溢出).请注意使用不接近",由于精度限制可能导致错误,因此检查浮点数是否完全相等是不明智的-更好地实施某种描述的足够接近"检查.
  • negative integral exponents (since x-y = 1/xy);
  • the undefined case of 00; and
  • overflow if you do not have arbitrary-precision values (basically, if (x * y) / y != x, you can be reasonably certain an overflow has occurred). Note the use of "not close to", it's unwise to check floats for exact equality due to potential for errors due to precision limits - far better to implement a "is close enough to" check of some description.

在转换为C或C ++时要记住的一件事,当使用最负的整数时,2的补码实现会引起问题,因为由于正负值之间的不平衡,它的负数通常又再次变为相同的值.这很可能导致无限递归.

One thing to keep in mind when translating to C or C++, a 2's complement implementation will cause issues when using the most negative integer, since its negation is often the same value again again due to the imbalance between the positive and negative values. This is likely to lead to infinite recursion.

您可以通过以下方式简单地解决此问题:

You can fix that simply by detecting the case early on (before anything else), with something like:

if INT_MIN == -INT_MAX - 1 and exp == INT_MIN:
    throw bad_input

其中第一部分检测2的补码实现,而第二部分检测 INT_MIN 作为指数的使用(有问题).

The first part of that detects a 2's complement implementation, while the second detects the (problematic) use of INT_MIN as an exponent.

这篇关于如何编写一个计算功率的循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆