#!/usr/bin/perl -slw use strict; my @logfact = ; sub hypergeom { # There are m "bad" and n "good" balls in an urn. # Pick N of them. The probability of i or more successful selections: # (m!n!N!(m+n-N)!)/(i!(n-i)!(m+i-N)!(N-i)!(m+n)!) my ($n, $m, $N, $i) = @_; my $loghyp1 = $logfact[ $m ] + $logfact[ $n ] + $logfact[ $N ] + $logfact[ $m + $n - $N ]; my $loghyp2 = $logfact[ $i ] + $logfact[ $n - $i ] + $logfact[ $m + $i - $N ] + $logfact[ $N - $i ] + $logfact[ $m + $n ]; return exp($loghyp1 - $loghyp2); } print hypergeom( 300, 700, 100, 40 );