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