scanf("%d",&a);
for(b=1;b<=a;++b)
{
c*=b;
}
printf("%lu",c);
我想得到100的答案!
100的阶乘。我怎样才能得到这个?(我想获得更大范围的数字)我们不能将数字限制为无穷大吗?
scanf("%d",&a);
for(b=1;b<=a;++b)
{
c*=b;
}
printf("%lu",c);
我想得到100的答案!
100的阶乘。我怎样才能得到这个?(我想获得更大范围的数字)我们不能将数字限制为无穷大吗?
几乎在每个(现代)平台上,最大整数范围都是2^31 - 1
(尽管按照标准,int
只需要至少 16 位)。对于您给定的平台,它将被定义INT_MAX
为<limits.h>
.
100!
显然会远远超过这个。要计算这么大的 in C
,您需要一个大整数库,例如GMP。
就像警告一样,如果您决定尝试使用 a double
(可以容纳这种大小的数字),由于精度损失,您将得到错误的答案。这很容易发现 - 在我的机器上,最后一位数字是48
,这显然是无稽之谈:100!
必须能被 100 整除,因此必须有00
最后两位数字。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#if __STDC_VERSION__>=199901L
#include <inttypes.h>
#else
#define PRIu16 "hu"
#endif
typedef struct _unums {
size_t size;
uint16_t *nums;//array
} UNums;
void UNums_init(UNums *num, uint16_t n){
num->nums = (uint16_t*)malloc(sizeof(uint16_t));
num->nums[0] = n;
num->size = 1;
}
void UNums_mul(UNums *num, uint16_t n){
uint16_t carry = 0;
size_t i;
for(i=0;i<num->size;++i){
uint32_t wk = n;
wk = wk * num->nums[i] + carry;
num->nums[i] = wk % 10000;
carry = wk / 10000;
}
if(carry){
num->size += 1;
num->nums = (uint16_t*)realloc(num->nums, num->size * sizeof(uint16_t));
num->nums[i] = carry;
}
}
void UNums_print(UNums *num){
size_t i = num->size;
int w = 0;
do{
--i;
printf("%0*" PRIu16, w, num->nums[i]);
if(!w) w = 4;
}while(i!=0);
}
void UNum_drop(UNums *num){
free(num->nums);
num->nums = NULL;
}
int main( void ){
UNums n;
uint16_t i;
UNums_init(&n, 1);
for(i=2;i<=100;++i)
UNums_mul(&n, i);
UNums_print(&n);//100!
UNum_drop(&n);
return 0;
}
对于较小的数字,您最好unsigned long long
使用int
. 但是您仍然对可以使用的最大数字有限制a
。您可以尝试double
,float
但您可能会遇到进动错误。
您可以使用GMP 库
安装:
sudo apt-get install libgmp3-dev
主.c:
#include <gmp.h>
void f() tooBigForYourShell {
mpz_t n; // declare a big n number
mpz_init_set_ui(n,0); // assign 0 as starting value
mpz_setbit(n, 1UL << 24); // set bit 2^24 (index 2^24 and not 24...) as 1.
gmp_printf("%Zd\n", n); // display the result
}
int main() {
tooBigForYourShell();
return 0;
}
编译:
gcc main.c -lgmp && ./a.out
???
profit, enjoy your 2^(2^24) number on stdout.
理论上,您最多可以使用 37 个使用位(所以 2^38 - 1 ?),但要小心,因为它会占用大量 CPU。
/!\ 如果您选择 2^(2^37),我不对任何损害负责。