【问题标题】:How do you calculate negative powers in C using iteration?您如何使用迭代计算 C 中的负幂?
【发布时间】:2020-06-14 21:46:08
【问题描述】:

我正在用 C 语言编写一个函数,它接受浮点数和整数幂,并计算基数^幂

到目前为止,我有:

float powIteration(float base, int power){
    if (power == 0){
        return 1;
    }
    else if (power > 0){
         for (int i = 0; i <= power; i++){
            base *= base;
       }
        return base;
    }
    else if (power < 0){
        for (int i = 0; i <= power; i++){
            base *= base;
        }
        return 1/base;
    }
}

我已经使用递归解决了这个问题。但我也想使用迭代来做到这一点。但由于某种原因,这段代码会导致 2^-​​2 = 0.5

此外,这种方法甚至可以实现所谓的“迭代方法”吗?

【问题讨论】:

  • i &lt;= power 如果power &lt; 0,您希望for 循环运行多少次?
  • 在我看来循环应该是
  • 哦,你说得对。有办法解决吗?还是代码的结构需要改变?
  • power = -power 会解决这个问题
  • 我的意思是你的正能量不起作用,f(2.0,2) 给 256,你也需要记住原来的基数

标签: c iteration pow


【解决方案1】:

小心这种类型的构造

if (...) { }
else if (...) { }
else if (...) { }
//   ^^^^^^^^      Why the 'if'? It should just be an 'else' 

你的编译器甚至可以警告你:

警告:非 void 函数不会在所有控制路径中返回值 [-Wreturn-type]

循环在几个方面是错误的

else if (power > 0) {
    for (int i = 0; i <= power; i++) {
    //                ^^   That's an off by one error. Likely.          
        base *= base;
    //  ^^^^^^             That's another algorithm. I'll show you later.       

正如 cmets 中已经指出的,这里还有另一个问题

else if (power < 0) {
//       ^^^^^^^^^                        So, power is negative...
    for (int i = 0; i <= power; i++) {
    //       ^^^^^  ^^^^^^^^^^  ^^^       But 'i' will never be.     

那个循环永远不会被执行,这就是为什么当输入为 2 时你得到 0.5,-2。


有很多方法可以完成这项任务。

double pow_iterative(double base, int power)
{
    if (power == 0) {
        return 1;
    }
    // Use a variable different from base, to store the partials.
    double result = 1.0;

    // That's another approach, so that you can write a single loop.
    if ( power < 0 ) {
        base = 1.0 / base;
        power = -power;
    }

    // Note that we are modifying 'result', not base.
    for (int i = 0; i < power; ++i) {
        //           ^^^
        result *= base;
    }

    return result;
}

另一种算法称为平方求幂

double pow_(double base, int power)
{
    double result = 1.0;
    if ( power < 0 ) {
        base = 1.0 / base;
        power = -power;
    }
    for(;;) {
        // If the power is odd, multiply once and "consume" the power
        //                     b^n = b * b^(n-1)
        if ( power % 2 ) {
            result *= base;
            --power; 
        }
        // It may have been consumed or 0 from the beginning
        if ( power == 0 )
            break;
        // The power is an even one, so we can square the base and halve the power
        //              b^(2n) = b^(n + n) = b^n * b^n = (b * b)^n
        base *= base;
        power /= 2;
    }
    return result;
}

你可以试试here

【讨论】:

    【解决方案2】:

    我发现第一个错误就立即回答了最后一个错误,所以我想我会去测试并帮助你解决这个问题。

    首先,您在每次迭代时都在更改 base,但您不希望这样,否则您将没有每次相乘的值,而是每次迭代都有一个不同的值。就像 pm100 说的:你要记住你原来的基地。例如:使用base=2power=-3

    i=0 -> base *= base; 2*2 = 4;
    i=1 -> now base is 4 so: 4*4 = 16;
    i=2 -> now base is 8 so: 8*8 = 64; and you want it to be 2*2*2
    

    最后1/value会给你正确答案

    也在你的负for循环中:你让你的for循环从0开始,如果你的力量是,比如说-2,那么它不符合你的运行条件i &lt;= power,因为你的i总是&gt; power; 应该是这样的:

    for (int i = power+1; i<0; i++)
    

    我为你做了一些改变:

    float powIteration(float base, int power){
        float num=base;
        if (power == 0){
            return 1;
        }else if (power > 0){
             for (int i = 1; i < power; i++){
                num=num*base;
           }
            return num;
        }else if (power < 0){
            for (int i = power+1; i<0; i++){
               num=num*base;
            }
            return 1/num;
        }
    }
    

    【讨论】:

    • 非常感谢!
    猜你喜欢
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 2017-08-06
    • 1970-01-01
    • 2017-04-06
    相关资源
    最近更新 更多