Code Comments
Programming Forum and web based access to our favorite programming groups.Hi,
I have the following code that uses Inline::C to compute factorial.
The problem is that whenever I use large N (>30) it began to return "INF".
I thougtht my C implementation already cater large number by using "float"?
Additionally I have already added Math::Pari as an attempt to solve
the problem, but again no avail.
Can anybody suggest what's the way to deal with this?
Here is my complete code:
#----------Beginning of my code ---------------
#!/usr/bin/perl -w
use Inline C;
use strict;
use Data::Dumper;
use Math::Pari qw/ :int/;
my $n = factrl(30); # it fails if I try factrl(40)
print "$n\n"
__END__
__C__
#include <stdio.h>
float factrl(int n)
{
float gammln(float xx);
void nerror(char error_text[]);
static int ntop=4;
static float a[33]={1.0,1.0,2.0,6.0,24.0};
int j;
if (n<0) nerror("Negative factorial in routine factrl");
if (n>32) return exp(gammln(n+1.0));
while (ntop<n){
j = ntop++;
a[ntop]=a[j]*ntop;
}
return a[n];
}
float gammln(float xx)
{
double x,y, tmp,ser;
static double cof[6] = {76.18009172947146, -86.50532032941677,
24.01409824083091, -1.231739572450155,
0.12086509738661e-2, -0.5395239384953e-5};
int j;
y = x = xx;
tmp= x+5.5;
tmp -= (x+0.5)*log(tmp);
ser=1.000000000190015;
for (j=0;j<=5;j++) ser += cof[j]/++y;
return -tmp+log(2.5066282746310005*ser/x);
}
#-----End of My Code--------------
--
Edward WIJAYA
Singapore
Post Follow-up to this messageOn Sat, 26 Mar 2005 12:22:18 +0800, ewijaya@singnet.com.sg (Edward Wijaya) wrote: >Hi, > >I have the following code that uses Inline::C to compute factorial. >The problem is that whenever I use large N (>30) it began to return "INF". > >I thougtht my C implementation already cater large number by using "float"? >Additionally I have already added Math::Pari as an attempt to solve >the problem, but again no avail. > >Can anybody suggest what's the way to deal with this? > >Here is my complete code: Change every occurence of the word "float" , in your script, to "double". -- I'm not really a human, but I play one on earth. http://zentara.net/japh.html
Post Follow-up to this messageHi Zentara, Thanks for the reply. On Sat, 26 Mar 2005 21:35:17 +0800, zentara <zentara@highstream.net> wrote: > Change every occurence of the word "float" , in your script, > to "double". It worked, but still limited. It overflowed when N>500. Most of the value of N, I use are around 1000-2000. Any other possibility? -- Edward WIJAYA Singapore
Post Follow-up to this messageOn 26 Mar, Edward Wijaya wrote: > > It worked, but still limited. It overflowed when N>500. > Most of the value of N, I use are around 1000-2000. > > Any other possibility? Try "long double" instead, which gives you 10 Bytes and the format char %Lf.
Post Follow-up to this messageHi Steven, On Sat, 26 Mar 2005 22:08:44 +0800, Steven Schubiger <steven@accognoscere.org> wrote: > Try "long double" instead, which gives you 10 Bytes and > the format char %Lf. > Still wont' do. It still return 'inf' for N>500 -- Edward WIJAYA Singapore
Post Follow-up to this messageOn 26 Mar, Edward Wijaya wrote:
> Still wont' do. It still return 'inf' for N>500
What does printf("%i\n", sizeof(long double)); tell you?
The byte sizes of variable types can vary from platform to platform.
Post Follow-up to this message> On 26 Mar, Edward Wijaya wrote: > Still wont' do. It still return 'inf' for N>500 Another solution would be, dynamically allocating memory: long double var; var = (long double *) malloc(2*sizeof(long double));
Post Follow-up to this messageOn 26 Mar, Edward Wijaya wrote: > > It gives: > 12 Fine, it was even 2 Bytes bigger than excepted. typedef (malloc(2*sizeof(long double))) Big_Double; Big_Double var; var should measure 24 bytes in size, which should suffice; if not, increment the factor accordingly.
Post Follow-up to this messageOn Sat, 26 Mar 2005 22:31:52 +0800, Steven Schubiger
<steven@accognoscere.org> wrote:
> typedef (malloc(2*sizeof(long double))) Big_Double;
> Big_Double var;
>
Sorry my C is barely Novice.
Where can I put this snippet in my C subroutine?
like this:
[snip code]
__END__
__C__
typedef (malloc(2*sizeof(long double))) Big_Double;
Big_Double factrl;
double factrl(int n)
{
double gammln(double xx);
void nerror(char error_text[]);
static int ntop=4;
static double a[33]={1.0,1.0,2.0,6.0,24.0};
int j;
if (n<0) nerror("Negative factorial in routine factrl");
if (n>32) return exp(gammln(n+1.0));
while (ntop<n){
j = ntop++;
a[ntop]=a[j]*ntop;
}
return a[n];
}
double gammln(double xx)
{
double x,y, tmp,ser;
static double cof[6] = {76.18009172947146, -86.50532032941677,
24.01409824083091, -1.231739572450155,
0.12086509738661e-2, -0.5395239384953e-5};
int j;
y = x = xx;
tmp= x+5.5;
tmp -= (x+0.5)*log(tmp);
ser=1.000000000190015;
for (j=0;j<=5;j++) ser += cof[j]/++y;
return -tmp+log(2.5066282746310005*ser/x);
}
--
Edward WIJAYA
Singapore
Post Follow-up to this messageOn 26 Mar, Edward Wijaya wrote: > Sorry my C is barely Novice. > Where can I put this snippet in my C subroutine? It's fine, as it is. Typedefs most often reside in header files, although, they can be used in the main file without suffer. If you ever should get bored, read the Perl Sources.
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.