Fortran Combination is not working correctly -- fortran 90

AI Thread Summary
The discussion revolves around a Fortran program designed to calculate combinations (nCr) using a factorial function. The initial code encounters issues when calculating combinations for larger values, specifically n=13 and r=2, due to integer overflow when calculating factorials. The factorial of 13 (13!) exceeds the maximum value for a 32-bit signed integer, leading to incorrect results.To address this, participants suggest changing the data type of the factorial function to a larger integer type, such as int64, which can handle larger values. Additionally, they recommend optimizing the combination calculation by avoiding the direct computation of large factorials. Instead, the program can be modified to compute only the necessary terms in the combination formula that do not cancel, thus preventing overflow and improving efficiency. The correct output for n=13 and r=2 should be 78, highlighting the need for accurate calculations without exceeding data type limits.
Md. Abde Mannaf
Messages
20
Reaction score
1
Code:
!subprogram for combination
!Author:: mannaf

function fact(n)
    implicit none
   integer ::fact,n,i
    fact=1
     do i=1,n
        fact=fact*i
    end do
    return
    end

program comb
    implicit none
    integer ::fact,n,r,combination
    print*,'enter the value of nCr'
    read*,n,r
if ( n>=0 .and. r>=0 .and. n>=r) then
combination=fact(n)/(fact(n-r)*fact(r))
print*,'combination is =',combination
else
    print*,'combination is not possible  '
end if

end program

when we input n=13,r=2 then result is not correct? how to solve?
 
Technology news on Phys.org
Md. Abde Mannaf said:
Code:
!subprogram for combination
!Author:: mannaf

function fact(n)
    implicit none
   integer ::fact,n,i
    fact=1
     do i=1,n
        fact=fact*i
    end do
    return
    end

program comb
    implicit none
    integer ::fact,n,r,combination
    print*,'enter the value of nCr'
    read*,n,r
if ( n>=0 .and. r>=0 .and. n>=r) then
combination=fact(n)/(fact(n-r)*fact(r))
print*,'combination is =',combination
else
    print*,'combination is not possible  '
end if

end program

when we input n=13,r=2 then result is not correct? how to solve?

What is the problem statement? What is the code supposed to do?

BTW, I've enclosed your program in "code" tags -- it helps the readability a lot. Just use [ code ] and [ /code ] (without the spaces) around your program code when posting here. :smile:
 
  • Like
Likes Md. Abde Mannaf
13! = 6,227,020,800. If the default largest signed integer allowed is Int32, that is 2,147,483,647. So Int32 is not large enough to hold the number 13! You need to specify that fact is int64. That will allow signed integers up to 9,223,372,036,854,775,807. That will be large enough for 20!, but not for 21!. You can still calculate larger combinatorial expressions, but you will have to cancel common factors of numerator and denominator to avoid such large factorials.
 
Last edited:
  • Like
Likes berkeman
Md. Abde Mannaf said:
Code:
!subprogram for combination
!Author:: mannaf

function fact(n)
    implicit none
   integer ::fact,n,i
    fact=1
     do i=1,n
        fact=fact*i
    end do
    return
    end

program comb
    implicit none
    integer ::fact,n,r,combination
    print*,'enter the value of nCr'
    read*,n,r
if ( n>=0 .and. r>=0 .and. n>=r) then
combination=fact(n)/(fact(n-r)*fact(r))
print*,'combination is =',combination
else
    print*,'combination is not possible  '
end if

end program

when we input n=13,r=2 then result is not correct? how to solve?
What did you get for a result? The correct answer is 78.

Your factorial function looks OK, although it doesn't give the correct answer for 0!, which is 1, by definition.

Edit: As FactChecker notes, 13! will overflow the capacity of a 4-byte signed integer.
 
  • Like
Likes Md. Abde Mannaf
If you need large numbers try to define nfactorial as real.
 
Md. Abde Mannaf said:
Code:
!subprogram for combination
!Author:: mannaf

function fact(n)
    implicit none
   integer ::fact,n,i
    fact=1
     do i=1,n
        fact=fact*i
    end do
    return
    end

program comb
    implicit none
    integer ::fact,n,r,combination
    print*,'enter the value of nCr'
    read*,n,r
if ( n>=0 .and. r>=0 .and. n>=r) then
combination=fact(n)/(fact(n-r)*fact(r))
print*,'combination is =',combination
else
    print*,'combination is not possible  '
end if

end program

when we input n=13,r=2 then result is not correct? how to solve?

If you try to calculate combinations by a "brute force" method, like trying to compute nCr = n! / [(n-r)! * r!], as you have found, you will run into issues of precision when evaluating factorials of large numbers. This is a side effect of using only a fixed number of bytes to represent fixed point (integer) or floating point (real) numbers.

By analyzing the formula for calculating a combination, we can see that computing the factorials in the numerator and denominator and then doing the division leads to a certain number of cancellations. Why not exploit this situation and only calculate the terms in the combination formula which do not cancel?
 
  • Like
Likes Md. Abde Mannaf and theodoros.mihos
Here it is, purposely put together in an unacceptable fashion, so make sure to work your way out of this one
Code:
program comb
    integer i, n, r
    read(*,*) n, r
    if ( n >= 0 .and. r >= 0 .and. n>=r ) then
        write(*,*) 'Number of combinations is =', torial()/fact()
    else
        write(*,*) "No can do"
    end if    
contains
integer function fact()
    fact = 1      
    do i = 1, r
        fact = fact*i    
    end do    
end function fact
integer function torial()
    torial = 1      
    do i = n-r+1, n        
        torial = torial*i    
    end do    
end function torial
end program comb
 
  • Like
Likes Md. Abde Mannaf

Similar threads

Replies
4
Views
2K
Replies
5
Views
23K
Replies
8
Views
2K
Replies
2
Views
6K
Replies
12
Views
3K
Replies
11
Views
2K
Back
Top