我用 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 returns 14100654080.000000,正好是上面的十倍。
也许我使用的数据类型有一些“限制”?我不确定。
A float
只有大约 7 位小数的精度。任何比这个数字多的数字都只是一个近似值。
如果您切换到 double
,您将获得大约 16 位精度。
当您开始使用 C 中的 基本 数据类型处理大数时,您可能 运行 会遇到麻烦。
整数类型的取值范围有限(例如 4x109 对于 32 位无符号整数)。浮点类型有更大的范围(虽然不是无限的)但精度有限。例如,IEEE754 双精度可以在 +/-10308
范围内为您提供大约 16 位十进制数字的精度
要恢复这两个 这些方面,您需要使用某种 bignum 库,例如 MPIR。
您的变量 x 是 int
类型。最常见的内部表示是 32 位。这是一个带符号的二进制数,因此只有 31 位可用于表示大小,通常的最大正整数值为 2^31 - 1 = 2,147,483,647。任何更大的东西都会溢出,给出更小的幅度并且可能是负号。
为了更大的范围,可以把x的类型改成long long
(通常是64位——大约18位)或者double
(通常是64位,精度为51位)大约 15 位数字)。
(警告:许多实现对 int
和 long
使用相同的表示,因此使用 long
可能不会有所改进。)
如果您在 C 程序中混合使用不同的数据类型,则编译器会执行多个隐式转换。由于编译器的工作方式有严格的规则,因此人们可以准确地弄清楚你的程序会发生什么以及为什么。
由于我不知道所有这些转换规则,我做了以下操作:估计最大结果所需的最大精度。然后将过程中的每个变量和函数显式转换为这种精度,即使这不是必需的。通常这会像解决方法一样工作。
我用 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 returns 14100654080.000000,正好是上面的十倍。
也许我使用的数据类型有一些“限制”?我不确定。
A float
只有大约 7 位小数的精度。任何比这个数字多的数字都只是一个近似值。
如果您切换到 double
,您将获得大约 16 位精度。
当您开始使用 C 中的 基本 数据类型处理大数时,您可能 运行 会遇到麻烦。
整数类型的取值范围有限(例如 4x109 对于 32 位无符号整数)。浮点类型有更大的范围(虽然不是无限的)但精度有限。例如,IEEE754 双精度可以在 +/-10308
范围内为您提供大约 16 位十进制数字的精度要恢复这两个 这些方面,您需要使用某种 bignum 库,例如 MPIR。
您的变量 x 是 int
类型。最常见的内部表示是 32 位。这是一个带符号的二进制数,因此只有 31 位可用于表示大小,通常的最大正整数值为 2^31 - 1 = 2,147,483,647。任何更大的东西都会溢出,给出更小的幅度并且可能是负号。
为了更大的范围,可以把x的类型改成long long
(通常是64位——大约18位)或者double
(通常是64位,精度为51位)大约 15 位数字)。
(警告:许多实现对 int
和 long
使用相同的表示,因此使用 long
可能不会有所改进。)
如果您在 C 程序中混合使用不同的数据类型,则编译器会执行多个隐式转换。由于编译器的工作方式有严格的规则,因此人们可以准确地弄清楚你的程序会发生什么以及为什么。
由于我不知道所有这些转换规则,我做了以下操作:估计最大结果所需的最大精度。然后将过程中的每个变量和函数显式转换为这种精度,即使这不是必需的。通常这会像解决方法一样工作。