For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > March 2005 > How can I get Inline::C to deal with big number?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author How can I get Inline::C to deal with big number?
Edward Wijaya

2005-03-26, 8:56 am

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
Zentara

2005-03-26, 3:55 pm

On 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
Edward Wijaya

2005-03-26, 3:55 pm

Hi 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
Steven Schubiger

2005-03-26, 3:55 pm

On 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.
Edward Wijaya

2005-03-26, 3:55 pm

Hi 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
Steven Schubiger

2005-03-26, 3:55 pm

On 26 Mar, Edward Wijaya wrote:

[color=darkred]
> 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.

Steven Schubiger

2005-03-26, 3:55 pm


> On 26 Mar, Edward Wijaya wrote:


[color=darkred]
> 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));

Steven Schubiger

2005-03-26, 3:55 pm

On 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.


Edward Wijaya

2005-03-26, 3:55 pm

On 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
Steven Schubiger

2005-03-26, 3:55 pm

On 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.

Edward Wijaya

2005-03-26, 3:55 pm

Dear Steven,

Sorry, don't mean to nitpick.

On Sat, 26 Mar 2005 23:09:26 +0800, Steven Schubiger
<steven@accognoscere.org> wrote:

> On 26 Mar, Edward Wijaya wrote:


> It's fine, as it is. Typedefs most often reside in header files,
> although, they can be used in the main file without suffer.


As per your suggestion, I tried the code like this:

http://sial.org/pbot/8640

But it gives some glitches, as shown here:
http://sial.org/pbot/8641

What could be the problem?
Is there a way to solve it


--
Edward WIJAYA
Singapore
Steven Schubiger

2005-03-28, 8:55 am

On 26 Mar, Edward Wijaya wrote:

> What could be the problem?
> Is there a way to solve it


I assume, the typedef doesn't value the "hooked" malloc, thus,
I recommend:

long double *big_double;
big_double = (long double *) malloc(2*sizeof(long double));

--
The trouble with having an open mind, of course,
is that people will insist on coming along and trying to put things in it.
-- Terry Pratchett
John W. Krahn

2005-03-28, 8:55 am

Steven Schubiger wrote:
> On 26 Mar, Edward Wijaya wrote:
>
>
> I assume, the typedef doesn't value the "hooked" malloc, thus,
> I recommend:
>
> long double *big_double;
> big_double = (long double *) malloc(2*sizeof(long double));

^^^^^^^^^^^^^^^
http://www.eskimo.com/~scs/C-faq/q7.7.html


John
--
use Perl;
program
fulfillment
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com