How to Add 2 Arbitrarily Sized Integers in C++

Arbitrary size integers in C/C++

You can't create integers of size less than char (that is, each object has a size in bytes that's a multiple of sizeof(char), which is 1). But that's not a problem since you can pack numbers inside a larger number.

const unsigned size_in_bits = 3;
unsigned a = 1; // 001
unsigned b = 5; // 101
unsigned packed = (b << size_in_bits*1) | (a << size_in_bits*0); // 101001
unsigned unpacked_a = (packed >> size_in_bits*0) & ((1 << size_in_bits)-1);
unsigned unpacked_b = (packed >> size_in_bits*1) & ((1 << size_in_bits)-1);

or use bitfields (the syntax is nicer, but the binary layout is implementation-defined)

struct Date
{
unsigned day : 5;
unsigned month : 4;
unsigned year : 21;
};

Date d;
d.day = 5; d.month = 11; d.year = 2014;

Add and subtract integers of arbitrary size

mp_limb_t mpn_add_n (mp_limb_t *rp, const mp_limb_t *s1p, const mp_limb_t *s2p, mp_size_t n)

and

mp_limb_t mpn_sub_n (mp_limb_t *rp, const mp_limb_t *s1p, const mp_limb_t *s2p, mp_size_t n)

in GMP are what you were looking for.

How to get arbitrarily large numbers in c++?

Use a Bignumber library, I prefer TTMath for its simplicity. You can find it here Link to tttmath. TTTmath allows for operation on large numbers but You may need to make your own toString method.

Here is an example of TTTmath in use from their Samples page:

#include <ttmath/ttmath.h>
#include <iostream>

int main()
{
ttmath::UInt<2> a,b,c;

a = "1234";
b = 3456;
c = a*b;

std::cout << c << std::endl;
}
Listing nr 1

Is there a gcc function to add two large numbers for C?

No, there is no compiler support in GCC for arbitrary-precision arithmetic. You would need to use a library like GMP. If you can use C++ instead of C, you can get a more "natural" API (with arithmetic operators, etc.) by using a library like Boost Multiprecision.

GCC does support, as an extension, the types __int128 and unsigned __int128, which can be used like any other integral type, but these only provide capacity for 38 decimal digits.

Edit: Also, as an aside, don't use macros (like #define type unsigned) to rename types. Instead this should be written with the typedef keyword like so: typedef unsigned type;

Printing multiple integers as one arbitrarily long decimal string

This is a bit unclear.

Of course, a function such as

void print_1024bit(uint64_t digits[]);

could be written to do this. But if you mean if any of the standard library's printf()-family of functions can do this, then I think the answer is no.

As you probably saw in the other question, the core of converting a binary number into a different base b is made of two operations:

  • Modulo b, to figure out the current least significant digit
  • Division by b, to remove that digit once it's been generated

When applied until the number is 0, this generates all the digits in reverse order.

So, you need to implement "modulo 10" and "divide by 10" for your 1024-bit number.

For instance, consider the number decimal 4711, which we want to convert to octal just for this example:

  1. 4711 % 8 is 7, so the right-most digit is 7
  2. 4711 / 8 is 588
  3. 588 % 8 is 4, the next digit is 4
  4. 588 / 8 is 73
  5. 73 % 8 is 1
  6. 73 / 8 is 9
  7. 9 % 8 is 1
  8. 8 / 8 is 1
  9. 1 % 8 is 1
  10. 1 / 8 is 0, we're done.

So, reading the bold digits from the bottom and up towards the right-most digits, we conclude that 471110 = 111478. You can use a calculator to verify this, or just trust me. :)

Handle arbitrary length integers in C++

The official site (http://www.ttmath.org/) has samples of using integers (ttmath::Int<2> a,b,c;) and floating points (ttmath::Big<1,2> a,b,c;) both. Just treat these like high precision int/float without members and everything should be fine. If the error remains, can you post the full error message, and the lines of code that it errored on?



Related Topics



Leave a reply



Submit