The wrong with factorial function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Blue sky

    The wrong with factorial function

    Hi,I am a new C++ learner.The follow prgram produces a wrong
    result,but I can't find the wrong.Can you help me?Thank you!

    #include<stdio. h>

    long factorial( long number);

    int main()
    {
    int a;

    for ( a = 0;a<10;a++ ){
    printf("%2d! = %1d\n",a,factor ial( a ));
    }

    return 0;
    }

    long factorial( long number )
    {
    if ( number <=1 ){
    return 1;
    }
    else{
    return ( number * factorial(numbe r - 1));
    }

    the result as follows
    0! = 1
    1! = 1
    2! = 2
    3! = 6
    4! = 24
    5! = 120
    6! = 720
    7! =5040
    8! = -25216
    9! = -30336
    Atentions,pleas e.The result 8! and 9! are wrong.But Why?
  • Gordon Burditt

    #2
    Re: The wrong with factorial function

    >Hi,I am a new C++ learner.

    Then why are you posting in comp.lang.c?
    Your program does look like C, though.
    >The follow prgram produces a wrong
    >result,but I can't find the wrong.Can you help me?Thank you!
    factorials of numbers tend to be large, so expect overflow. You'll
    overflow a signed long at 13! and a signed int at 8!. What is the
    value of INT_MAX in <limits.hon your system? 32767?
    >#include<stdio .h>
    >
    >long factorial( long number);
    >
    >int main()
    >{
    int a;
    >
    for ( a = 0;a<10;a++ ){
    printf("%2d! = %1d\n",a,factor ial( a ));
    You are printing a long with a %d format, which is supposed to be
    used for ints. Use %ld. This is likely to cause all sorts of
    trouble. Here, it seems to have taken a piece of the (32-bit?)
    result and printed it as a (16-bit?) int.
    }
    >
    return 0;
    }
    >
    >long factorial( long number )
    >{
    if ( number <=1 ){
    return 1;
    }
    else{
    return ( number * factorial(numbe r - 1));
    }
    >
    the result as follows
    >0! = 1
    >1! = 1
    >2! = 2
    >3! = 6
    >4! = 24
    >5! = 120
    >6! = 720
    >7! =5040
    >8! = -25216
    >9! = -30336
    >Atentions,plea se.The result 8! and 9! are wrong.But Why?

    Comment

    • Richard Heathfield

      #3
      Re: The wrong with factorial function

      Blue sky said:
      Hi,I am a new C++ learner.
      This is comp.lang.c, not comp.lang.c++.

      Fortunately, your question is actually about a C program!
      The follow prgram produces a wrong
      result,but I can't find the wrong.Can you help me?Thank you!
      I already did so, yesterday, in alt.comp.lang.l earn.c-c++. I suggest you go
      read that reply.

      --
      Richard Heathfield <http://www.cpax.org.uk >
      Email: -http://www. +rjh@
      Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
      "Usenet is a strange place" - dmr 29 July 1999

      Comment

      • Martin Ambuhl

        #4
        Re: The wrong with factorial function

        Blue sky wrote:
        Hi,I am a new C++ learner.The follow prgram produces a wrong
        result,but I can't find the wrong.Can you help me?Thank you!
        [...]
        Atentions,pleas e.The result 8! and 9! are wrong.But Why?
        Luckily, none of your code involves C++ rather than C. If it had,
        then questions about it would not be topical here, since C++ is a
        different language.

        Note what happens with the following code on your machine and think
        about what that might mean. You might also try the same code with
        'signed' instead of 'unsigned' and SHRT_MAX, LONG_MAX, and LLONG_MAX
        instead of USHRT_MAX, ULONG_MAX, and ULLONG_MAX. Notice what happens then.

        #include <stdio.h>
        #include <limits.h>

        int main(void)
        {
        unsigned int i, usok = 1, ulok = 1, ullok = 1;
        unsigned short usfact = 1;
        unsigned long ulfact = 1;
        unsigned long long ullfact = 1;
        printf("[Output]\n"
        "The limiting values are implementation-specific.\n\n") ;
        for (i = 1; ullok; i++) {
        if (usok) {
        if (USHRT_MAX / i < usfact) {
        printf("%u! will overflow an unsigned short.\n"
        "An unsigned short is at most %u.\n", i,
        USHRT_MAX);
        usok = 0;
        }
        else {
        usfact *= i;
        ulfact *= i;
        ullfact *= i;
        printf("%u! is %u (unsigned short)\n", i, usfact);
        }
        }
        if (!usok && ulok) {
        if (ULONG_MAX / i < ulfact) {
        printf("%u! will overflow an unsigned long.\n"
        "An unsigned long is at most %lu.\n", i,
        ULONG_MAX);
        ulok = 0;
        }
        else {
        ulfact *= i;
        ullfact *= i;
        printf("%u! is %lu (unsigned long)\n", i, ulfact);
        }
        }
        if (!ulok) {
        if (ULLONG_MAX / i < ullfact) {
        printf("%u! will overflow an unsigned long long.\n"
        "An unsigned long long is at most %llu.\n", i,
        ULLONG_MAX);
        ullok = 0;
        }
        else {
        ullfact *= i;
        printf("%u! is %llu (unsigned long long)\n", i,
        ullfact);
        }
        }

        }
        return 0;
        }

        [Output]
        The limiting values are implementation-specific.

        1! is 1 (unsigned short)
        2! is 2 (unsigned short)
        3! is 6 (unsigned short)
        4! is 24 (unsigned short)
        5! is 120 (unsigned short)
        6! is 720 (unsigned short)
        7! is 5040 (unsigned short)
        8! is 40320 (unsigned short)
        9! will overflow an unsigned short.
        An unsigned short is at most 65535.
        9! is 362880 (unsigned long)
        10! is 3628800 (unsigned long)
        11! is 39916800 (unsigned long)
        12! is 479001600 (unsigned long)
        13! will overflow an unsigned long.
        An unsigned long is at most 4294967295.
        13! is 6227020800 (unsigned long long)
        14! is 87178291200 (unsigned long long)
        15! is 1307674368000 (unsigned long long)
        16! is 20922789888000 (unsigned long long)
        17! is 355687428096000 (unsigned long long)
        18! is 640237370572800 0 (unsigned long long)
        19! is 121645100408832 000 (unsigned long long)
        20! is 243290200817664 0000 (unsigned long long)
        21! will overflow an unsigned long long.
        An unsigned long long is at most 184467440737095 51615.

        Comment

        Working...