c程序计算阶乘。 [英] c program to calculate factorial.

查看:83
本文介绍了c程序计算阶乘。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好家伙

我正在运行这个计算数字的阶乘的程序

----------------- ------------------------

hello guys
I am running this program which calculate the factorial of a number
-----------------------------------------

#include <stdlib.h>
#include <conio.h>

long fact(int);

int main()
{
  int n;
  long f;
     while(true){
  printf("Enter a number\n");
  scanf("%d", &n);

  if (n < 0)
    printf("Please enter a positive number.\n");
  else
  {
    f = fact(n);
    printf("%d! = %ld\n", n, f);
  }              
  }//end while
    getch();
  return 0;
}

long fact(int n)
{
  if (n == 0)
    return 1;
  else
    return(n * fact(n-1));
}



------------------------------ ------------

当我运行它时输入数字31

我得到的数字是:738197504这是不正确的当我输入更大的数字时,我得到一个负面结果



我知道长数据类型大小是4个字节,可以存储大于该数字



当我输入数字65267时程序崩溃



我在不同的IDE上运行这个程序(Borlnd,代码: :Blocks)我得到了不同的结果(在我输入65244时它会在代码块上崩溃)





我需要知道长数据的原因类型不能正常工作,它不存储正确的数字以及不同IDE上不同结果的原因是什么



希望我的英语帮助我表达我的观点是正确的。

非常感谢


------------------------------------------
and when I run it I input the number 31
and I get the number: 738197504 which is not correct and when I input bigger number I get a negative result

I know that the "long" data type size is 4 bytes which can store bigger than that number

and when I enter the number 65267 the program crashs

I ran this program on different IDEs(Borlnd, Code::Blocks) and I got different results(on codeblocks it crashes when I input 65244)


I need to know why the long data type doesn't work correctly, it doesn't store the right number and what's the reason for the different results on different IDEs

hope that my English helped me to express my viewpoint correctly.
thank you very much

推荐答案

因子值增长很快。非常非常快:

Factorial values grow fast. Very, very fast:
n	n!
0	1
1	1
2	2
3	6
4	24
5	120
6	720
7	5040
8	40320
9	362880
10	3628800
11	39916800
12	479001600
13	6227020800
14	87178291200
15	1307674368000
16	20922789888000
17	355687428096000
18	6402373705728000
19	121645100408832000
20	2432902008176640000
25	1.5511210043E25
42	1.4050061178E51
50	3.0414093202E64
70	1.1978571670E100
100	9.3326215444E157
450	1.7333687331E1,000
1000	4.0238726008E2,567
3249	6.4123376883E10,000

(来源: Wiki [ ^ ]

如果你看长 - 你说的4个字节 - 那不是64位数.4个字节是4 * 8 == 32位,所以它可以存储的最大数字是2,147,483,647 ...所以你的方法在12点耗尽了!并回到随机数字。



W¯¯ iki表截断并清理 - OriginalGriff [/ edit]





谢谢你,但为什么我输入的数字大于12我得到错误的结果??





这都与计算机存储数字的方式有关。让我们只使用较少的位(或者我必须依靠0键太长时间(并假设一个int仅包含四位。



显然,它可以存储的最大数字是每个位是'1'对吗?1111b(或0xF或15十进制)。



错误。如果我们这样做,我们无处可存储负数,因为数字的正面性或负面性需要一点点来存储它。

传统上,计算机使用最高或最左边的位数表示负数:最高位设置的任何值都是负数,并且清除(或0)时该值为正。

因此我们可以存储的最大值是0111b(或者十进制和十进制的7) - 值范围

(Source: Wiki[^]
And if you look at long - 4 bytes as you say - that's not a 64 bit number. 4 bytes is 4 * 8 == 32 bits, so the largest number it can store is 2,147,483,647...so your method "runs out of steam" at 12! and wraps back to a "random" number.

[edit]Wiki Table truncated and cleaned - OriginalGriff[/edit]


"thank you but why when I input bigger numbers than 12 I get wrong results??"


This all has to do with how computers store numbers. Lets just work with a smaller number of bits (or I have to lean on the "0" key for far too long( and assume that an int contaiuns just four bits.

Obviously, the largest number it can store is when each bit is '1' right? 1111b (or 0xF or 15 in decimal).

Wrong. If we did that, we would have nowhere to store negative numbers, because the "positiveness" or "negativeness" of a number needs a bit to store it.
Conventionally, computers use the highest, or left most bit to indicate negative numbers: any value with the "top bit" set is negative, and with it clear (or '0') the value is positive.
So the largest value we can store is 0111b (or 7 in hex and decimal) - the values range

0111b   7
0110b   6
0101b   5
0100b   4
0011b   3
0010b   2
0001b   1
0000b   0
1111b  -1
1110b  -2
1101b  -3
1100b  -4
1011b  -5
1010b  -6
1001b  -7
1000b  -8 or "negative zero" depending on the system.

因此,当你添加2 + 3时,你得到5:

So, when you add 2+3, your get 5:

 0010b   2
+0011b   3
=0101b   5

但是当你加5 + 6时会发生什么?

But what happens when you add 5 + 6?

 0101b   5
+0110b   6
=1011b  -5

Arrggh! Noooooooo!但这就是所发生的事情 - 加上0101b和0110b的额外位进入最高位,因此数字变为负数。如果你继续添加到这个,那么你也会溢出顶部位,并且在那时结果开始变得非常不可预测,并且将根据你运行的系统,你使用的编译器,编译而变化你设置的开关和许多其他(主要是相当沉闷的)效果。



并且不要忘记,乘法是(在它最基本的)只是很多添加起来! :笑:



当你将它扩展到32位时,你在尝试超过整数的2,147,483,647时会遇到同样的问题:因为它的值是

0111111111111111111111111111111111111111111111111111111111111111二进制。添加一个,它变为负数,你的问题就开始......:笑:

Arrggh! Noooooooo! But that is what happens - the "extra" bit from the addition of 0101b and 0110b moves into the "top bit" so the number becomes negative. If you continue to add to this then you will "overflow" the "top bit" as well, and at that point the result start to become very unpredictable and will vary depending on the system you run on, the compiler you use, the compilation switches you set and a host of other (mostly rather dull) effects.

And don't forget, multiplication is (at it's most basic) just a lot of adding up! :laugh:

When you scale this up to 32 bits, you get the same problems the moment you try to exceed 2,147,483,647 in an integer: because it's value is
0111111111111111111111111111111111111111111111111111111111111111 in binary. Add one, and it goes negative and your problems begin...:laugh:


如果你想从中获得更多一点,试试这个:

If you want to get out a little bit more from it, try this:
#include <stdlib.h>

unsigned long long fact(int);

int main()
{
  int n=31;
  unsigned long long f;
  f = fact(n);
  printf("%d! = %llu\n", n, f);
  return 0;
}

unsigned long long fact(int n)
{
  if (n == 1)
    return 1;
  else
    return(n * fact(n-1));
}



正如您将看到的,这仍然不够。 31!= 2.6525285981219105863630848e + 32,表示33位十进制数字。如果你想要这个位,计算log2(31!)。您将得到112.6,这意味着您需要一个113位长(15字节)变量来保存这样的值。好吧,C没有这样的标量类型。据我所知,没有语言具有标量类型这么大的数字类型 - 这并不意味着你不能处理这些对象(例如c#中有BigInteger,但这不是标量类型,它是一类)。在C中你可以使用这个库: http://sourceforge.net/projects/bignlibacbignum/ [ ^ ]


这篇关于c程序计算阶乘。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆