战俘不适用于两个两位数的数字

时间:2019-10-08 11:32:07

标签: c

我编写了一个代码,从标准输入和输出(到标准输出)A到B的幂读取两个长整数(A和B)。

它适用于1 ^一些巨大数字,3 ^ 3等

但不适用于13 ^ 16。

我试图用long int ans来解决它,它给了我不同的价值,但不是正确的价值。


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

int main()
{
    int x, n;
    long int ans;
    scanf("%d \n %d",&x, &n);

    ans = pow(x,n);

    printf("%d", ans);
    return 0;
}

3 个答案:

答案 0 :(得分:2)

pow(1,anything)始终为1。pow(3, 3)为27。它们都是非常小的数字,可以轻松装入32位整数。 pow(13,16)是(大约)6.65 x 10 17 。对于32位整数而言,这个太大了。它将变成一个64位整数(尽管pow(14, 17)不会)。您的编译器可能会将long视为32位值,这种情况并不少见。您可以尝试使用long long(可能是64位)或int64_t(明确地是64位长)。

请注意,pow()的原型是

double pow(double x, double y);

这意味着它将返回一个双精度浮点数,然后将其强制转换为变量的类型。 double(64位浮点数)的尾数只有53位精度,这意味着当您将其转换回64位整数时,您将无法获得确切的数字。您可以使用原型为

powl()
long double powl(long double x, long double y);

但是long double可以定义为80位或128位,甚至只能定义为64位(Microsoft)。它可能会为您提供所需的精度,但是幂运算的本质就是如此,您的输入数字不必变得更大就可以溢出甚至最长的long double的精度。

如果您确实需要将大数提高为大数,则将需要一个大的整数库。

答案 1 :(得分:0)

您已经将ins定义为int,然后尝试将其打印为int(%d-使用下一个参数并将其打印为int),因此将printf("%d", ans)更改为printf("%ld",ans)。您的代码如下所示:

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

    int main()
    {
        int x, n;
        long int ans;
        scanf("%d \n %d",&x, &n);

        ans = pow(x,n);

        printf("%ld", ans);
        return 0;
    }

答案 2 :(得分:0)

使用整数幂函数,而不是使用浮点数pow()和具有潜在的有限精度的朋友来解决64位以内的整数问题(13 16 需要60位)。

unsigned long long upow(unsigned  x, unsigned y) {
  unsigned long long z = 1;
  unsigned long long xx = x;
  while (y) {
    if (y % 2) {
      z *= xx;
    }
    y /= 2;
    xx *= xx;
  }
  return z;
}

int main() {
  printf("%llu\n", upow(3, 3));
  printf("%llu\n", upow(13, 16));
}

输出

27
665416609183179841

如果代码需要处理更多的64位答案,请考虑使用long double(可能会降低精度)或big_integer库。