working with big numbers

A

ashu

Dear Friends,
i need to know how to calculate big numbers i.e. factorial of 100. i
google and found a solution but didn`t understand how it is done.and
some others solution is using some library .but i actually want to
develop a solution witch i understand. kindly give me some logic?
atleast i need to know how to start with.
thankx
 
T

thomas.mertes

Dear Friends,
i need to know how to calculate big numbers i.e. factorial of 100.
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

i google and found a solution but didn`t understand how it is done.and
some others solution is using some library .but i actually want to
develop a solution witch i understand. kindly give me some logic?
atleast i need to know how to start with.
thankx

There are programming languages with built-in unlimited
precision integer support. E.g. Seed7. With Seed7 I was able
to computer the factorial of 100 with the expression: !100_
For details see:

http://seed7.sourceforge.net/manual/types.htm#bigInteger

Languages which don't have unlimited precision integers
can use libraries instead. See: http://gmplib.org


Regards,
Thomas Mertes

--
Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.
 
T

thomas.mertes

Dear Friends,
i need to know how to calculate big numbers i.e. factorial of 100. i
google and found a solution but didn`t understand how it is done.and
some others solution is using some library .but i actually want to
develop a solution witch i understand. kindly give me some logic?
atleast i need to know how to start with.
thankx

I forgot to post a function, which computes the factorial.
Here it is:

$ include "seed7_05.s7i";
include "bigint.s7i";

(**
* Compute the factorial of a bigInteger number.
* @return the factorial of the number.
* @exception NUMERIC_ERROR The number is negative.
*)
const func bigInteger: factorial (in bigInteger: number) is func
result
var bigInteger: factorial is 1_;
local
var integer: num is 0;
begin
if number < 0_ then
raise NUMERIC_ERROR;
else
for num range 2 to ord(number) do
factorial *:= bigInteger conv num;
end for;
end if;
end func;

const proc: main is func
begin
writeln(factorial(100_));
end func;
--------- end of file ----------


Regards,
Thomas Mertes

--
Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.
 
B

bl0ckedusersoft

Dear Friends,
i need to know how to calculate big numbers i.e. factorial of 100. i
google and found a solution but didn`t understand how it is done.and
some others solution is using some library .but i actually want to
develop a solution witch i understand. kindly give me some logic?
atleast i need to know how to start with.
thankx

I posted this a few months back and nobody answered.
I guess it will be useful this time.

It is C code to calculate big factorials. It requires no
special libraries, as it implements the "big number" code
itself.

big-factorial.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DIG 1000000 /* maximum number of digits */

void bignum_add(char*, char*);
void bignum_put(char*);

int main(int argc, char** argv)
{
char bignum_1[DIG] = {0};
char bignum_2[DIG] = {0};

int i, j = 0, k = 0;

bignum_1[DIG - 1] = 1;

if(argc < 2){
printf("use: %s n\n", argv[0]);
exit(0);
}
sscanf(argv[1], "%d", &i);

while(i--){
memcpy(bignum_2, bignum_1, DIG);
for(j = i; j>0; j--)
bignum_add(bignum_1, bignum_2);
}

bignum_put(bignum_1);
return 0;
}

void bignum_put(char* a){
int i = 0;
while(!a) ++i;
while(i < DIG) putchar(a[i++] + '0');
putchar('\n');
}

void bignum_add(char* a, char* b){
char carry[DIG];
int i = DIG - 1;
int x = 0;

carry = 0;

while(i >= 0){
carry[i - 1] = 0;
a += b;
a += carry;
if(a > 9){
if(i > 0){
carry[i - 1] = a / 10;
a -= (char)(a / 10) * 10;
} else {
printf("integer overflow\n");
exit(0);
}
}
i--;
}
}


(I'm posting this using Google Groups since this
news item has not yet? appeared in my newsreader).

Bl0ckeduser
 
B

Barry Schwarz

Dear Friends,
i need to know how to calculate big numbers i.e. factorial of 100. i
google and found a solution but didn`t understand how it is done.and
some others solution is using some library .but i actually want to
develop a solution witch i understand. kindly give me some logic?
atleast i need to know how to start with.

Discussing in the concrete how a particular solution works is probably
going to be more informative than discussing a hypothetical solution
in the abstract. Which solution did you find (and where)? What don't
you understand about it?

If you really want to reinvent the wheel, one popular approach is to
use dynamically allocated arrays of char to store decimal values
between 0 and 9. These arrays are processed by subroutines that mimic
the standard pencil and paper operations (such as add the units
column, detect any carry, add the tens column with carry, detect any
carry, add the hundreds column with carry, detect carry, etc).
 
P

Paul

ashu said:
Dear Friends,
i need to know how to calculate big numbers i.e. factorial of 100. i
google and found a solution but didn`t understand how it is done.and
some others solution is using some library .but i actually want to
develop a solution witch i understand. kindly give me some logic?
atleast i need to know how to start with.
thankx

http://gmplib.org/#WHAT

Sample code using it - see "C++" section here.

http://rosettacode.org/wiki/Lucas-Lehmer_test

The GMP package supports both C and C++. The C routines
require more work, and the resulting code is less readable.
But the C code also uses less memory than the C++, as you can
reduce the number of intermediate variables in storage.
If your problem is small enough to fit within the cache of
the processor, there could be significant runtime benefits.

I took that sample code, and re-coded it in C, and it uses
less memory that way. I was testing to see how slow such a
method was, compared to Prime95 (which uses FFTs and assembler).

GMP comes with a manual.

http://gmplib.org/gmp-man-5.0.5.pdf

See in particular the section "12.1 C++ Interface General"
for how easy this can be. If you want to use the C routines,
you'll have to work harder (but it's worth it). If you don't
want to learn anything, try it in C++.

*******

There are also tools that run in a Unix shell, that
can perform arithmetic for you.

http://en.wikipedia.org/wiki/Bc_(Unix)

http://en.wikipedia.org/wiki/Dc_(computer_program)

Paul
 
R

Robert Miles

Dear Friends,
i need to know how to calculate big numbers i.e. factorial of 100. i
google and found a solution but didn`t understand how it is done.and
some others solution is using some library .but i actually want to
develop a solution witch i understand. kindly give me some logic?
atleast i need to know how to start with.
thankx

If you want to use the GMP package under Windows, you may want to investigate the Cygwin site. It provides an Linux emulation under Windows, with some free C compilers and a free Cygwin version of GMP.

For multiplications, the basic idea is to separate the numbers into sections, multiply one section of one number by one section of another, separate any carries or overflows from the result, repeat until all non-zero sectionsof each number are done, then add up all the pieces with proper attention to which section of the result they should contribute to.
 
I

Ike Naar

Dear Friends,
i need to know how to calculate big numbers i.e. factorial of 100. i
google and found a solution but didn`t understand how it is done.and
some others solution is using some library .but i actually want to
develop a solution witch i understand. kindly give me some logic?
atleast i need to know how to start with.
thankx

Just curious, what problem are you trying to solve that requires
calculating such big factorials?

If you only need an approximation, you could use Stirling's formula.

If you're trying to solve the famous programming exercise
"find the number of trailing zeroes of 1000!" then
you don't actually need to compute the factorial.
 
N

Nils M Holm

ashu said:
i need to know how to calculate big numbers i.e. factorial of 100. i
google and found a solution but didn`t understand how it is done.and
some others solution is using some library .but i actually want to
develop a solution witch i understand. kindly give me some logic?
atleast i need to know how to start with.
thankx

In principle, you could represent a number by an array of
digits and then implement the basic math operations on top
of this data type. You could implement these operations
in the same way as human beings perform them on a sheet of
paper.

For improved performance, you could use base-256 or base-2^32
or some other large-base arithmetics, i.e. use unsigned chars,
ints, or longs. Larger bases will require some more complex
algorithms, though, and conversion for printing such bignums
can be slow and painful.

For all the gory details, see the book "Scheme 9 from Empty Space"
on my homepages (URL below). It describes the bignum implementation
of a Scheme interpreter in C. The algorithms used in the book are
simple and easy to comprehend. The full public domain source code
is available on my home page.
 
I

Ike Naar

There are programming languages with built-in unlimited
precision integer support. E.g. Spam7. With Spam7 I was able
to computer the factorial of 100 with the expression: !100_

Plug (verb)
- to blatantly mention a particular product or service as if advertising it.
 
N

Nils M Holm

Ike Naar said:
Plug (verb)
- to blatantly mention a particular product or service as if advertising it.

While I agree that advertising can be annoying, it seems
to be a necessary evil.

If products (no matter whether free or commercial) were not
advertised, we would not know about them. If the Bell Labs
had not declared the existence of C, we would not use it
today and this newsgroup would not exist.

There seems to be a common hallucination implying that "good"
products magically find their way to the public without ever
being advertised. I have no idea how this is supposed to work,
but if you have any leads, I would be glad if you shared them.
 
J

James Dow Allen

i need to know how to calculate  big numbers  i.e. factorial of 100.

There are three options, depending on what your
underlying goals are. (I've done all three! ::whack:: )

1. Use an off-the-shelf bignum library. This is the
professional approach, but also perhaps the most
boring and the least fun.

2. Write your own bignum package. This could be a great
learning experience ... or a complete waste of time if
that experience doesn't fit your goals.

3. Do what I did once as a fast-and-dirty compromise;
use the C program as a front-end to 'bc'. ::whack::
For example,
% ln -s /dev/tty tty.c
% cc tty.c
main() {
int i;
for (i = 1; i < 100; i++)
printf("%d * ", i);
printf("%d\n", i);
}
^D
% a.out | bc


It is C code to calculate big factorials. It requires no
special libraries, as it implements the "big number" code
itself.

void bignum_add(char*, char*);
void bignum_put(char*);

Do you not also need bignum_multiply() ?

James Dow Allen
 
N

Noob

I posted this a few months back and nobody answered.
I guess it will be useful this time.

It is C code to calculate big factorials. It requires no
special libraries, as it implements the "big number" code
itself.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DIG 1000000 /* maximum number of digits */
int main(int argc, char** argv)
{
char bignum_1[DIG] = {0};
char bignum_2[DIG] = {0};

Declaring "huge" auto arrays is not the best idea.

You had better allocate such objects dynamically.

Regards.
 
B

Ben Bacarisse

James Dow Allen said:
Do you not also need bignum_multiply() ?

He uses repeated addition. It's a little slow, of course, but it fits
with the maxim that programmers should be lazy.
 
N

Nils M Holm

Ben Bacarisse said:
He uses repeated addition. It's a little slow, of course, but it fits
with the maxim that programmers should be lazy.

But then shifting and adding is just a little step away and
so much more efficient.
 
B

Ben Bacarisse

Nils M Holm said:
But then shifting and adding is just a little step away and
so much more efficient.

Yes, much more efficient, although that was not my point. However, if I
take my point to heart -- that one should write the minimum that gets
the job done -- there is a solution that is both a little simpler *and*
more efficient. All one needs is a function to multiply a "bignum" by
an ordinary (unsigned) int and that's only a few lines of code:

#include <stdio.h>
#include <stdlib.h>

unsigned mult(char *digits, unsigned len, unsigned n)
{
char *dp = digits;
unsigned carry = 0;
while (dp < digits + len || carry) {
unsigned p = *dp * n + carry;
*dp++ = p % 10;
carry = p / 10;
}
return dp - digits;
}

void print(char *digits, unsigned len)
{
if (len)
while (len--)
putchar('0' + digits[len]);
else putchar('0');
}

int main(int argc, char **argv)
{
unsigned n;
if (argc == 2 && (n = atoi(argv[1])) <= 1000) {
char product[3000] = {1}; /* enough for 1142! */
unsigned plen = 1;
while (n > 1)
plen = mult(product, plen, n--);
print(product, plen);
putchar('\n');
}
return 0;
}

This is way faster than repeated addition, and probably a little simpler
too.
 
I

Ike Naar

While I agree that advertising can be annoying, it seems
to be a necessary evil.

If products (no matter whether free or commercial) were not
advertised, we would not know about them. If the Bell Labs
had not declared the existence of C, we would not use it
today and this newsgroup would not exist.

There seems to be a common hallucination implying that "good"
products magically find their way to the public without ever
being advertised. I have no idea how this is supposed to work,
but if you have any leads, I would be glad if you shared them.

Mr. Mertes has been spamming the programming newsgroups for more
than six years. If his language is still unsuccessful, then perhaps
this approach is not as effective as you think.
 
B

Bl0ckeduser

(e-mail address removed) wrote:
Declaring "huge" auto arrays is not the best idea.

You had better allocate such objects dynamically.

Regards.

Good idea. I think a good dynamic allocation scheme
would save memory and allow my program to calculate larger
factorials much faster.

P.S. I'm also a noob.
 
B

Bl0ckeduser

This is way faster than repeated addition, and probably a little simpler
too.

Nice work. I have run them side-by-side and your version is indeed many
times faster.
 
P

Peter Nilsson

I.e. means 'that is'. It's possible you meant e.g. meaning 'for
example'.

The simplest way of working with big numbers is to store them
in arrays and use traditional pencil and paper methods to do
calculations. The example below just stores digits 0..9 in a
character array.

It's hard to give advice on how to understand something if you
haven't told us what it was you didn't understand.

That's because using existing libraries is often quicker and
easier than re-inventing the wheel.
It is C code to calculate big factorials. It requires no
special libraries, as it implements the "big number" code
itself.

big-factorial.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DIG 1000000     /* maximum number of digits */

I got bored after a minute of no output. Note that 100!
has nowhere near this number of digits.
void bignum_add(char*, char*);
void bignum_put(char*);

int main(int argc, char** argv)
{
        char bignum_1[DIG] = {0};
        char bignum_2[DIG] = {0};

I have a tentative rule not to allocate more than 256 bytes of
automatic storage if possible.

<snip>

Since we only need a factorial, and since we only need decimal
output, here's a simple way of calculating in blocks of 4 digits
at a time. I'll leave it as an exercise to modify it to work on
numbers higher than 9999!

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
int i;
size_t j, fc;
unsigned long n, N;
unsigned long a;
unsigned short *f = malloc(sizeof *f);

if (!f) return 0;

for (i = 1; i < argc; i++)
{
N = strtoul(argv, 0, 10);
if (N > 9999) return 0;

fc = 1;
*f = 1; /* f = 1 */

for (n = 2; n <= N; n++)
{
/* f *= n */
for (a = 0, j = 0; j < fc; j++)
{
a = f[j] * n + a;
f[j] = a % 10000;
a /= 10000;
}

if (a)
{ /* left over carry - expand the buffer */
fc++;
f = realloc(f, fc * sizeof *f);
if (!f) return 0;
f[j] = a;
}
}

/* backwards print the little endian result */
for (j = fc; j-- > 0; )
printf(j == fc - 1 ? "%hu" : "%04hu", f[j]);

putchar('\n');
}

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top