C幂函数,只能有一个for循环和一个if语句[已关闭]

bqujaahr  于 2023-02-07  发布在  其他
关注(0)|答案(2)|浏览(144)

已关闭。此问题需要超过focused。当前不接受答案。
**想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。

8小时前关门了。
Improve this question
我有一个面试练习题,我需要创建一个幂函数(不使用pow()或**),它可以查找所有边缘情况(指数〈0||exponent == 0)。另外,我被告知只能使用一个if语句和一个循环。我已经解决了这个问题,但由于边缘情况,我无法找到一种方法,只使用一个循环,一个if。有什么想法?

#include <stdio.h>

float power(int base, int exponent){
        if(exponent == 0) return 1;
        
        float result = 1;
        int i;

        if(exponent > 0){
            for(i = 0;i < exponent; i++){
                result *= base;
            }
        } else {
         for (i = 0; i > exponent; i--){
             result *= base;
         } 
         result = 1 / result;
        }
        
        return result;
    }

int main()
{
    int x = 2, y = -8;
    float result = power(x,y);
    printf("%.3f\n", result);
 
    return 0;
}
tkclm6bt

tkclm6bt1#

如果允许使用帮助函数,您可以执行以下操作:

#include <stdio.h>
 
float helper(int base, int exponent)
{
    float result = 1;
    for(int i = 0;i < exponent; i++)
    {
        result *= base;
    }
    return result;  
}

float power(int base, int exponent)
{
    if(exponent < 0) return 1/helper(base, -exponent);
    return helper(base, exponent);
}
 
int main()
{
    int x = 2, y = -8;
    float result = power(x,y);
    printf("%.3f\n", result);
 
    return 0;
}

顺便说一句:为了获得更好的精度,我建议使用double而不是float

    • 编辑:**

如果没有辅助函数,请考虑如下代码:

float power(int base, int exponent)
{
    float b = base;
    if (exponent < 0)
    {
        b = 1 / b;
        exponent = -exponent;
    }

    float result = 1;
    int i;

    for(i = 0;i < exponent; i++)
    {
        result *= b;
    }
    return result;
}

(同样:首选double,而不是float

iih3973s

iih3973s2#

我有一个面试练习题。......有什么想法?
记住目标是展示你在有一定限制的情况下编写C语言的能力和知识深度。代码应该:

  • 证明功能正常。
  • 在时间、内存和代码使用方面表现良好-没有十亿次循环。
  • 看起来格式统一、清晰。
  • 使用现代标准。例如 * compound literal *。

使用exponentiation by squaring
当指数很大时,像for(i = 0;i < exponent; i++){这样的迭代循环太慢了
正是这样的洞察力帮助区分了新手和有经验的程序员。
避免-exponent,因为当exponent == INT_MIN时,这是UB。
再一次,经验/洞察力的另一个标志。
使用double,因为float在从大多数int转换时会立即丢失精度。
更多的洞察力。

//  Power function with `int` arguments.
//  Only use one if statement and one loop.
double ipower(int base, int exponent) {
  if (exponent < 0) {
    // Avoid direct -exponent as that is UB when exponent == INT_MIN
    return 1.0/ipower(base, -1 - exponent)/base;
  }

  double fbase = base;
  double fpower = 1.0;
  while (exponent) {
    //        v-----------------------v  Compound literal 
    fpower *= (double[2]){ 1.0, fbase }[exponent & 1];
    fbase *= fbase;
    exponent /= 2;
  }
  return fpower;
}

包括测试线束。
有经验的程序员证明他们的代码是合理的,并提供评估方法。

#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>

int ipower_test(int base, int exponent) {
  double y0 = pow(base, exponent);
  double y1 = ipower(base, exponent);
  if (y0 != y1) {
    printf("%12d %12d\n", base, exponent);
    printf("%20a %24.17g\n", y0, y0);
    printf("%20a %24.17g\n", y1, y1);
    return 1;
  }
  return 0;
}

int ipower_tests(void) {
  const int b[] = { INT_MIN, -100, -2, -1, 0, 1, 2, 3, 100, INT_MAX };
  size_t bn = sizeof b/sizeof b[0];
  const int e[] = { INT_MIN, -100, -2, -1, 0, 1, 2, 3, 100, INT_MAX };
  size_t en = sizeof e/sizeof e[0];
  for (size_t bi = 0; bi < bn; bi++) {
    for (size_t ei = 0; ei < en; ei++) {
      ipower_test(b[bi], e[ei]);
    }
  }
  return 0;
}

int main() {
  return ipower_tests() == 0;
}
    • 高级**

小值范围下降到约4.94e-324,这比1.0/(最大值约为1.78e +308)小得多,因此将负幂分解为两步是明智的。

if (exponent < 0) {
    // Avoid direct -exponent as that is UB when exponent == INT_MIN
    // Further: as small value range deeper the large values, break into 2 calls.
    int half = exponent/-2;
    return 1.0/ipower(base, half)/ipower(base, -half - exponent);
  }

相关问题