Storing and printing integer values greater than 2^64 - c

I am trying to write a program for finding Mersenne prime numbers. Using the unsigned long long type I was able to determine the value of the 9th Mersenne prime, which is (2^61)-1. For larger values I would need a data type that could store integer values greater than 2^64.
I should be able to use operators like *, *=, > ,< and % with this data type.

You can not do what you want with C natives types, however there are libraries that let handle arbitrarily large numbers, like the GNU Multiple Precision Arithmetic Library.

To store large numbers, there are many choices, which are given below in order of decreasing preferences:
1) Use third-party libraries developed by others on github, codeflex etc for your mentioned language, that is, C.
2) Switch to other languages like Python which has in-built large number processing capabilities, Java, which supports BigNum, or C++.
3) Develop your own data structures, may be in terms of strings (where 100 char length could refer to 100 decimal digits) with its custom operations like addition, subtraction, multiplication etc, just like complex number library in C++ were developed in this way. This choice could be meant for your research and educational purpose.

What all these people are basically saying is that the 64bit CPU will not be capable of adding those huge numbers with just an instruction but you rather need an algorithm that will be able to add those numbers. Such an algorithm would have to treat the 2 numbers in pieces.
And the libraries they listed will allow you to do that, a good exercise would be to develop one yourself (just the algorithm/function to learn how it's done).

There is no standard way for having data type greater than 64 bits. You should check the documentation of your systems, some of them define 128 bits integers. However, to really have flexible size integers, you should use an other representation, using an array for instance. Then, it's up to you to define the operators =, <, >, etc.
Fortunately, libraries such as GMP permits you to use arbitrary length integers.

Take a look at the GNU MP Bignum Library.

Use double :)
it will solve your problem!

Related

Are the type bigger than unsigned long long int in c? [duplicate]

I am trying to write a program for finding Mersenne prime numbers. Using the unsigned long long type I was able to determine the value of the 9th Mersenne prime, which is (2^61)-1. For larger values I would need a data type that could store integer values greater than 2^64.
I should be able to use operators like *, *=, > ,< and % with this data type.
You can not do what you want with C natives types, however there are libraries that let handle arbitrarily large numbers, like the GNU Multiple Precision Arithmetic Library.
To store large numbers, there are many choices, which are given below in order of decreasing preferences:
1) Use third-party libraries developed by others on github, codeflex etc for your mentioned language, that is, C.
2) Switch to other languages like Python which has in-built large number processing capabilities, Java, which supports BigNum, or C++.
3) Develop your own data structures, may be in terms of strings (where 100 char length could refer to 100 decimal digits) with its custom operations like addition, subtraction, multiplication etc, just like complex number library in C++ were developed in this way. This choice could be meant for your research and educational purpose.
What all these people are basically saying is that the 64bit CPU will not be capable of adding those huge numbers with just an instruction but you rather need an algorithm that will be able to add those numbers. Such an algorithm would have to treat the 2 numbers in pieces.
And the libraries they listed will allow you to do that, a good exercise would be to develop one yourself (just the algorithm/function to learn how it's done).
There is no standard way for having data type greater than 64 bits. You should check the documentation of your systems, some of them define 128 bits integers. However, to really have flexible size integers, you should use an other representation, using an array for instance. Then, it's up to you to define the operators =, <, >, etc.
Fortunately, libraries such as GMP permits you to use arbitrary length integers.
Take a look at the GNU MP Bignum Library.
Use double :)
it will solve your problem!

Is it possible to create custom-width integers in C?

The C standard and C compilers come with fixed width integer types, such as uint8_t, int16_t, etc.
Is there a way of defining a 128-bit integer in C that would be useable in code using the same semantics as the existing fixed-width integers?
You'll need something like GMP:
http://gmplib.org/
You won't get the "exact" semantics.
Assuming you're programming a 64-bit machine, you could define a uint128_t type as a struct of two uint64_ts and implement just the arithmetic operators you need by hand. You'd have to manually handle carrying bits from the low 64 bits to the high or vice versa in the case of an operation that overflows in one or the other direction. (For example, add 0xFFFFFFFF to 0x00000001.) That would be much lighter-weight than using an entire library for arbitrary-size bignums like GMP. It'd be a bit tricky to write but by no means impossible--it's pretty much how the built-in BASICs on 8-bit computers back in the day handled math with numbers larger than 255, for example.

Type with fixed length > 64 in C

I'm currently writing some cryptographic code in C that has to deal with numbers greater than what uint64_t is able to hold. (It's for doing HDCP authentication, and one of the cipher values is 84 bits)
What would be the best way to do this? One of the variables I need to store is 84 bits long — should I take one uint64_t for the low 64 bits, and an uint32_t for the high 20 bits? This seems like a hack to me, but I'm not sure if there's really a better solution, especially for storing in a structure.
The ideal alternative would be declaring a custom datatype, like uint64_t, but instead 84 bits long, which behaves the same way. Is this even possible? I'm not sure if libc can handle variables with bit widths not multiples of 8, but an 88 bit type could work for that, although I'm not even sure how feasible declaring a custom bit-width data type is.
Edit: I've checked for uint128_t, but that doesn't seem to exist in clang's C99 mode. I'll be doing standard arithmetic and bit operations on this, the standard shebang associated with crypto code.
7 years ago my cryptography professor introduced us to MIRACL open source library, which contained a very fast implementation of cryptographic functions and the facilities to work on big precision numbers. It's been a long time since I used it, but it seems to be still in good shape. Maybe it's not ideal if your problem is simply to represent exactly 84-bit values and nothing else, but it might be a more general solution.
OK, I just installed a 32-bit Clang 3.1, and this works:
#include <stdio.h>
int main()
{
unsigned __int128 i;
printf("%d\n", sizeof(i));
}
(And prints "16".)
If you need more than 64 bits, and there is no integer type with more than 64 bits in the target environment, then you must use something else. You will have to use two variables, an array, or perhaps a struct with several members. You will also have to create the operations yourself, such as a plus function if you want to add numbers.
There is no built-in support in C to easily and automatically create N-bit integers.
What about the GNU Multiple Precision (GMP) library? It claims arbitrary precision:
GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers. There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on. GMP has a rich set of functions, and the functions have a regular interface.

What is the most efficient way to store and work with a floating point number with 1,000,000 significant digits in C?

I'm writing a utility to calculate π to a million digits after the decimal. On a 32- or 64-bit consumer desktop system, what is the most efficient way to store and work with such a large number accurate to the millionth digit?
clarification: The language would be C.
Forget floating point, you need bit strings that represent integers
This takes a bit less than 1/2 megabyte per number. "Efficient" can mean a number of things. Space-efficient? Time-efficient? Easy-to-program with?
Your question is tagged floating-point, but I'm quite sure you do not want floating point at all. The entire idea of floating point is that our data is only known to a few significant figures and even the famous constants of physics and chemistry are known precisely to only a handful or two of digits. So there it makes sense to keep a reasonable number of digits and then simply record the exponent.
But your task is quite different. You must account for every single bit. Given that, no floating point or decimal arithmetic package is going to work unless it's a template you can arbitrarily size, and then the exponent will be useless. So you may as well use integers.
What you really really need is a string of bits. This is simply an array of convenient types. I suggest <stdint.h> and simply using uint32_t[125000] (or 64) to get started. This actually might be a great use of the more obscure constants from that header that pick out bit sizes that are fast on a given platform.
To be more specific we would need to know more about your goals. Is this for practice in a specific language? For some investigation into number theory? If the latter, why not just use a language that already supports Bignum's, like Ruby?
Then the storage is someone else's problem. But, if what you really want to do is implement a big number package, then I might suggest using bcd (4-bit) strings or even ordinary ascii 8-bit strings with printable digits, simply because things will be easier to write and debug and maximum space and time efficiency may not matter so much.
I'd recommend storing it as an array of short ints, one per digit, and then carefully write utility classes to add and subtract portions of the number. You'll end up moving from this array of ints to floats and back, but you need a 'perfect' way of storing the number - so use its exact representation. This isn't the most efficient way in terms of space, but a million ints isn't very big.
It's all in the way you use the representation. Decide how you're going to 'work with' this number, and write some good utility functions.
If you're willing to tolerate computing pi in hex instead of decimal, there's a very cute algorithm that allows you to compute a given hexadecimal digit without knowing the previous digits. This means, by extension, that you don't need to store (or be able to do computation with) million digit numbers.
Of course, if you want to get the nth decimal digit, you will need to know all of the hex digits up to that precision in order to do the base conversion, so depending on your needs, this may not save you much (if anything) in the end.
Unless you're writing this purely for fun and/or learning, I'd recommend using a library such as GNU Multiprecision. Look into the mpf_t data type and its associated functions for storing arbitrary-precision floating-point numbers.
If you are just doing this for fun/learning, then represent numbers as an array of chars, which each array element storing one decimal digit. You'll have to implement long addition, long multiplication, etc.
Try PARI/GP, see wikipedia.
You could store its decimals digits as text in a file and mmap it to an array.
i once worked on an application that used really large numbers (but didnt need good precision). What we did was store the numbers as logarithms since you can store a pretty big number as a log10 within an int.
Think along this lines before resorting to bit stuffing or some complex bit representations.
I am not too good with complex math, but i reckon there are solutions which are elegant when storing numbers with millions of bits of precision.
IMO, any programmer of arbitrary precision arithmetics needs understanding of base conversion. This solves anyway two problems: being able to calculate pi in hex digits and converting the stuff to decimal representation and as well finding the optimal container.
The dominant constraint is the number of correct bits in the multiplication instruction.
In Javascript one has always 53-bits of accuracy, meaning that a Uint32Array with numbers having max 26 bits can be processed natively. (waste of 6 bits per word).
In 32-bit architecture with C/C++ one can easily get A*B mod 2^32, suggesting basic element of 16 bits. (Those can be parallelized in many SIMD architectures starting from MMX). Also each 16-bit result can contain 4-digit decimal numbers (wasting about 2.5 bits) per word.

big int compiler implementations?

i am building a compiler similar to c , but i want it to parse integers bigger than 2^32 . hows it possible?how has been big integers been implemented in python and ruby like languages ..!!
There are libraries to do this sort of thing.
Check out gmplib.
There are lots of big number libraries, see this wikipedia article for a complete list.
GMP(GNU Multiple Precision Arithmetic Library) is sufficient for everything I have encountered. NTL is more of the same but is object orientated.
Generally these libraries represent the numbers with arrays with each digit of a number as a character if you want to roll your own but it is a lot of work.
If you want to write it yourself, follow my trip through memory lane ;-).
In the old days, when computers used 8 bits. We often needed to calculate with big numbers (like > 255). And we all had to write the routines. For example the addition.
If we needed to add numbers of two bytes to each other we used the following algorithm:
Add the least significant bytes.
If the result exceeded 8 bits, the carry bit was set.
Add the most significant bytes and the carry flag (if set).
If the result exceeded 8 bits you produced an overflow error (but you don't need to do this if you want more that 2 bytes.
You can extend this to more bytes/words/dwords/qwords and to other operators.
I believe you'll need some sort of bigint library, which are available on the net, just do a bit of searching and you may find one that's suitable for your project.
Because, simply parsing the integers, I believe, will not be enough. Your users will want not only to store, but also, probably, perform operation with such numbers.
There is a slide by Felix von Leitner that covers some bignum basics. Personally i think it is quite informative and technical.
C++ Big Integer Library from Matt McCutchen
https://mattmccutchen.net/bigint/
C++ source code only. Very simple to use.
You would have to use some sort of struct in c to achieve this. You will find this is difficult if you are on and x86 platform and not x64 as well. If you're on x86, prepare to get very familiar with assembly and the carry flag.
Good luck!

Resources