How to handle a integer value bigger than the max int(64) can store? [duplicate] - 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

Efficient 8-bits and 16-bits computations in OCaml

I am currently working on a project in OCaml where I have to manipulate unsigned integers on 8 bits and on 16 bits. In my context, things can get a little messy, I sometimes want to convert an 8 bit integer into a 16 bits one, or split a 16 bits integer into two 8 bits one. I also want to use all the operations like addition, or the bitwise operations on those. Since there are all these interaction between 8 and 16 bits, I really like the comfort of having separate types for those. However, I still want my program to compute reasonnably efficiently, and I don't want to actually lose too much time casting an integer of a given size into another size. So my question is essentially how should I go about this? I have two main options but I don't know enough about the low-level interpretation of OCaml to comfortably chose:
Option 1 : Use dedicated types
I figured that I can use the Stdint library that is available through opam and has an implementation of the types uint8 and uint16 which are exactly what I am looking for.
Pros
I get very good mileage from the typing and will definitely avoid silly bugs from this
Cons
I have to constantly use the functions Uint8.to_uint16 and Uint16.to_uint8, which might eventually add up to heavy memory usage and poor efficiency of the compiled program, depending on how the precise representation is stored in machine
Option 2 : Encode everything within the type int
This means that all my integers will simply be of type int and I will have to program the addition of two 8-bits integers and of two 16-bits integers in this type, for instance.
Pros:
I think these operations can be programmed in a very efficient way using usual operations and the bitwise operations on the type int.
Cons:
I get essentially nothing from the typing and I have to trust myself to chose the right function at the right time.
Possible workaround
I could use two modules for defining 8-bits and 16-bits integers encoded in an int declared as private. I think that would essentially work like I presented with Option 2. The fact that I chose the type to be private would however mean that I cannot switch from one to the other without running into a typing mistake, thus forcing explicit casts and getting leverage from the type system. Still I expect the casts to be very efficient, since the memory representation of the object won't change.
So I would like to know how you would go about that? Is it worth going through all the trouble, do you think a solution is clearly better, or are they reasonably equivalent?
Bonus
Everytime I want to print (in hexadecimal) the value of a variable a of type uint8, I am writing
Printf.ksprintf "a = %02x" (Uint8.to_int a)
There is again a cast that seems to me a bit silly, I could also use direclty the Uint8.to_string_hex function, but it writes explicitly the 0x in front of the number, which I don't want. Ideally I would like to just write
Printf.ksprintf "a = %02x" (Uint8.to_int a)
Is there a way to change the scopes and do some magic with the Printf to make it happen?
In the stdint library both int8 and int16 are represented as int so there is no real tradeoff between option 1 and option 2,
type int8 = private int
(** Signed 8-bit integer *)
type int16 = private int
(** Signed 16-bit integer *)
The stdint library already provides you the best of two worlds, you have an efficient implementation and type safety. Yes, you need to do these translations but they no-ops and there only for the typechecker.
Also, if you're looking for modular arithmetic (and, in general, modeling machine words and bitvectors) then you can look at our Bitvec library, which we developed as part of the Binary Analysis Platform. It is focused on performance while still providing type safety and a lot of operations. We modeled it based on the latest SMT-LIB specification to give clear semantics to all operations. It uses the excellent Zarith library underneath the hood that enables efficient representation for small and arbitrary-length integers.
Since the modularity is not a property of a bitvector itself, but a property of an operation we do not encode the number of bits in the type and use the same type (and representation) for all bitvectors from 1-bits to thousands-of-bits. However, it is impossible to use mix-match the types incorrectly. E.g., you can use generic functions,
(x + y) mod m8
Or predefined modules for the specified modulus, e.g.,
M8.(x + y)
The library has a minimal number of dependencies, so try it by installing
opam install bitvec
There are also additional libraries like bitvec-order, bitvec-sexp, and bitvec-order that enable further integration with the Core suite of libraries, if you need them.

The use and the idea of integer to string conversion

I try to handle with big numbers in C++. One thing that I tried is installing the gmp library but this is not working properly on my computer (see this post). So I want to try another method and that is integer to string conversion.
But I dont get the idea of that. Let me make myself clear. For example we handle with a big integer. Lets say 2^1000. When, for example, I want to calculate 2^1000 mod 10 this is not possible (so far I know) with the normal libraries of c++. So my question is: Is it possible when converting my integer to a string and if the answer is yes:
How can I do arithmetic operations when I convert my integer to a string.
If you are using c++ predefined integer type, then 2^1000 is simply impossible. On your system maximum should be 2^16 or 2^32, max 2^64 (for long long). If you wanted to do that, you need to use (or implement yourself - what I don't recommend) infinite-precision integers.
You can convert normal int to string very easily with
... = std::to_string(/*Your int*/);
If you meant you want to do something like this:
amazing_to_string_conversion(1000000000000000000000000000000000000000000000)
It's not possible in any C++ implementation. The very number constant can't exist in code, it will many, many times overflow.
And if you consider implementing it yourself, it will probably K.O. you, because of very complicated calculations during division and non-trivial calculations like sqrt().

Seeking a GMP binary search: How to compare two GMP mpz_t's using memcmp?

Motivation: I want to use bsearch (binary search) to quickly search through a sorted list of 121-bit non-negative integers (they all have exactly 121 bits, although they may have leading zeroes). These integers are too large to stored as individual ints, and so on, so I'm planning on making them mpz_t (using GMP).
Looking through the manual, GMP doesn't have a bsearch equivalent (although, correct me if I'm wrong), which leads me to:
Question: Can we use memcmp or something similar to compare two non-negative integers with an equal number of bits stored as mpz_t? If so, what is the correct syntax?
If this is possible, searching should be quite efficient.
I'm also open to alternative suggestions as to (a) data structures for storing these 121-bit integers that admit rapid searching in C++, (b) methods for searching through the integers that doesn't use memcmp.
If they're only 121 bit integers, why not use native 128 bit int extensions: http://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html ? That should be much faster, as you can avoid any "costly" operations like memcpy, all of your comparisons should be one instruction.

Type for large currency values in C++

What type should i use in C++ to store large currecy values like 5231451.3245114414? It should allow to store 10 or even more decimal digits.
It depends on how large your values are, and more importantly on the required precision.
If all numbers have the same precision and scale, say 10 places after the decimal point and no bigger than one million, then you could just use long integers (multiply everything by 1010, etc.).
If you truly need arbitrary scales and precision, you won't get around an arbitrary-precision library. A quick search turned up mpdecimal, but there may be others. Combining the fixed-point approach with arbitrary precision, you could also just use libgmp for arbitrary-precision integers but treat them all as units of 1010.
You probably need a custom type that mimics what Java's BigDecimal does.
A 64-bit double precision number is only accurate to 17 digits, so you'll have to do better than that.
You may try to check if GMP suits what you need. It got a C++ wrapper if I remember correctly.
If you have to work with monetary values you probably want a fixed-point decimal class, so something like this should do the trick.
Since you want all that precision (out of curiosity: why do you need that for monetary amounts?) you should probably use a 64 bit integer as its base type (it should be enough for up to ~18 total decimal digits). If that still isn't enough you'll have to use some biginteger library to have an arbitrarily-big integer as the base for the fixed point decimal class.
Have you looked at decNumber++? Link can be found at http://speleotrove.com/decimal/ ?
Thanks you all for your answers. I found the most appropriate solution myself. It's just one file that does everything i need - C++ wrapper class for the OLE Automation type DECIMAL. It's really light (no additional heavy libraries or files) and powerfull and can handle REALLY BIG numbers.

how do I declare an integer variable of 1024 bits in length?

I'm trying to write an algorithm for a number theory/computer science merged class that can factor large numbers in better than exponential time. I am using the g++ compiler on a 64 bit machine but when I chain together long it will only allow me to do up to 2 longs. Is there any way to tell it to use an arbitrary amount of space for a variable?
If you want just a collection of longs, you can declare an array of longs. But you don't want that. You want https://mattmccutchen.net/bigint/ BigIntegers :-)
Alternatives:
http://gmplib.org/
http://www.mpir.org/
(disclaimer: I haven't tested/used them)
Or if you want to implement them
How to implement big int in C++
I'll add that the C++ std library doesn't contain a big integer implementation (source STL big int class implementation )
You'll need a library. A good one is http://gmplib.org/