繁体   English   中英

我在 C 中编写了一个程序,它接受两个输入,x 和 n,并将 x 提高到 n 次方。 10^10 不起作用,发生了什么?

[英]I've made a program in C that takes two inputs, x and n, and raises x to the power of n. 10^10 doesn't work, what happened?

我在 C 中编写了一个程序,它接受两个输入,x 和 n,并将 x 提高到 n 次方。 10^10 不起作用,发生了什么?

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

float isEven(int n)
{
    return n % 2 == 0;
}

float isOdd(int n)
{
    return !isEven(n);
}

float power(int x, int n)
{
    // base case
    if (n == 0)
    {
        return 1;
    }
    // recursive case: n is negative
    else if (n < 0)
    {
        return (1 / power(x, -n));
    }
    // recursive case: n is odd
    else if (isOdd(n))
    {
        return x * power(x, n-1);
    }
    // recursive case: n is positive and even
    else if (isEven(n))
    {
        int y = power(x, n/2);
        return y * y;
    }
    
    return true;
}

int displayPower(int x, int n)
{
    printf("%d to the %d is %f", x, n, power(x, n));
    return true;
}

int main(void)
{
    int x = 0;
    printf("What will be the base number?");
    scanf("%d", &x);
    
    int n = 0;
    printf("What will be the exponent?");
    scanf("%d", &n);
    
    displayPower(x, n);
}

例如,这是一对有效的输入:

./exponentRecursion 
What will be the base number?10
What will be the exponent?9
10 to the 9 is 1000000000.000000

但这就是我用 10^10 得到的:

./exponentRecursion 
What will be the base number?10
What will be the exponent?10
10 to the 10 is 1410065408.000000

为什么会写出这么奇怪的数字?

顺便说一句,10^11 返回 14100654080.000000,正好是上面的十倍。

也许我正在使用的数据类型有一些“限制”? 我不知道。

float仅对大约 7 个十进制数字具有足够的精度。 任何位数多于该数字的数字都只是一个近似值。

如果你切换到double你会得到大约 16 位的精度。

当您开始使用 C 中的基本数据类型处理大数时,您可能会遇到麻烦。

整数类型的值范围有限(例如 4x10 9表示 32 位无符号整数)。 浮点类型具有更大的范围(尽管不是无限的)但精度有限。 例如,IEEE754 双精度可以为您提供大约 16 位十进制数字的精度,范围为 +/-10 308

要恢复这两个方面,您需要使用某种 bignum 库,例如MPIR

您的变量 x 是int类型。 最常见的内部表示是 32 位。 这是一个有符号二进制数,因此只有 31 位可用于表示幅度,通常的最大正 int 值为 2^31 - 1 = 2,147,483,647。 任何更大的都会溢出,给出更小的幅度,可能是负号。

对于更大的范围,您可以将 x 的类型更改为long long (通常为 64 位——大约 18 位)或double (通常为 64 位,大约 15 位的精度为 51 位)。

(警告:许多实现对intlong使用相同的表示,因此使用long可能不是一种改进。)

如果您在 C 程序中混合不同的数据类型,编译器会执行几个隐式转换。 由于编译器的工作方式有严格的规则,人们可以准确地弄清楚你的程序会发生什么以及为什么。

由于我不知道所有这些铸造规则,我做了以下事情: 估计最大结果所需的最大精度。 然后将过程中的每个变量和函数显式转换为这个精度,即使没有必要。 通常,这将像解决方法一样工作。

暂无
暂无

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

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