ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have a new assignment and that is to write a C program that knows how to handle very long integers (no limits).
I'm looking for a better and more efficient than representing it as a string or linked list. Thanks.
BTW, why not a linked list?
If you really need no limits integers, linked lists are the best (only?) way. At least in terms of effort/efficiency ratio.
With a C-string, you trade space for complexity and computation, while a linked list is a lot easier to work with, but there is (slightly) more overhead (pointers for every node in the least).
There is no "silver bullet" though, at least not that I can think of. Actually maybe there is some sort of binary tree you could make that splits/creates children when something is overflowed, and then to display the number you can walk all of the nodes in ..some order?.. and just append all of the contents. That would change the performance from linear to logarithmic.
Yes, but a vector is nothing more than an object-oriented implementation of a linked list.
I'm not certain that is true. I thought that a vector was a malloc'd (or new in C++) array (usually with some spare elements), which when it ran out of space was realloc'd (again allocating some spare elements). Meaning that random access is possible but time to input elements is variable depending upon whether it extra elements need to be reallocated, and the whole array copied from one version to the next.
I'm not certain that is true. I thought that a vector was a malloc'd (or new in C++) array (usually with some spare elements), which when it ran out of space was realloc'd (again allocating some spare elements). Meaning that random access is possible but time to input elements is variable depending upon whether it extra elements need to be reallocated, and the whole array copied from one version to the next.
Hmm, you are probably right. Unlike linked lists nodes, vector elements can also be accessed by index IIRC (true?). This may be useful for implementing no-limits-int's. But IMHO features like allocating memory in advance is not a valid argument, but just an efficient implementation decision, which can also be done for linked lists.
Quote:
Originally Posted by graemef
This could be an approach to use.
Well, yes and no. Yes: because it could prove handy for implementing no-limit-integers. No: because the OP asked for a C solution, not C++...
OK guys so it seems that I'm stucked with the linked list. How about every link contains more than 1 digit (of the number). I think this is more efficient (time and mem space) but more difficult to implement the 4 operations. What do you think? Thank you.
First you need to figure out how to calculate things such as * and / (or just log, then form the others in terms of log and +/-.) If you can figure out how to do this with unlimited bytes, the representation then becomes a matter of trial and error.
ta0kira
If you are using a linked list then in your root node include the sign and number of digits (which will roughly equate to nodes)
First look at operations to assign a value in and to display your number:
Next look at the comparison operators: > >= == < <=
Then tackle addition, and subtraction - relatively easy
Then multiplication, again fairly easy
Finally div and mod, which can be built using repeated addition and then subtraction.
Then all you need to do is test, document and relax
No: because the OP asked for a C solution, not C++...
But a vector can be implemented in C, just as a linked list can be implemented. I was just outlining how it may be implemented in a language neutral way
Oh, that's babbling. The essential idea is that you must use a decimal representation and program the computer to do the math like they (used to) teach you in second and third grade.
I would extend the binary size for these 2 reasons:
1- Best space use.
2- You may take advantage of the binary arithmetic of the CPU. Then transforming it from/to decimal would take less time than manual decimal math.
PS: I believe that a single realloc() on a linear buffer is better than linked lists or binary trees. I would use a flag to indicate whether a number is negative to know beforehand if there would be an "overflow" in addition
Code:
struct number {
uint32_t *words;
size_t size;
int negative;
}
Also, you may store each word as big-endian to quickly implement the shift operations.
Probably not applicable since this is an assignment, but the openssl library (installed on most linux boxes) has a bignum package which handles all the operations you could want on arbitrary length integers. type "man 3ssl bn" at your terminal to read about it.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.