Combination is not working correctly -- fortran 90

Click For Summary

Discussion Overview

The discussion revolves around a Fortran 90 program intended to calculate combinations (nCr) using a factorial function. Participants are exploring issues related to the correctness of the output when specific values are input, particularly focusing on the limitations of integer types and potential overflow problems.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • Some participants note that the factorial function may lead to overflow when calculating large values, such as 13!, which exceeds the capacity of a 4-byte signed integer.
  • One participant suggests using int64 for the factorial variable to accommodate larger values, while another mentions that this would still not be sufficient for values like 21!.
  • There is a suggestion to define the factorial function as a real number to handle larger results more effectively.
  • Some participants discuss the inefficiency of calculating combinations using the factorial method directly, proposing instead to exploit cancellations in the formula to avoid large intermediate values.
  • A participant points out that the factorial function does not correctly return 1 for 0!, which is a known mathematical definition.
  • Another participant presents an alternative implementation of the combination calculation, although it is noted to be poorly structured.

Areas of Agreement / Disagreement

Participants express differing views on how to handle large numbers in the calculation of combinations. There is no consensus on a single solution, as multiple approaches and considerations are presented.

Contextual Notes

Participants highlight limitations related to integer overflow and precision issues when using fixed-size data types for large factorial calculations. The discussion remains open regarding the best method to calculate combinations without encountering these issues.

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   Reactions: 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   Reactions: 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   Reactions: 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   Reactions: 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   Reactions: Md. Abde Mannaf

Similar threads

  • · Replies 5 ·
Replies
5
Views
5K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 5 ·
Replies
5
Views
23K
  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 2 ·
Replies
2
Views
7K
  • · Replies 12 ·
Replies
12
Views
3K
  • · Replies 11 ·
Replies
11
Views
2K