7

http://www.boost.org/doc/libs/1_53_0/libs/multiprecision/doc/html/index.html

I just started exploring this library. There doesn't seem to be a way to convert cpp_int into an array of bytes.

Can someone see such functionality?

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
NFRCR
  • 5,304
  • 6
  • 32
  • 37
  • I'm guessing you want it to be able to send it e.g. over a network connection? I actually recommend against using the raw data, instead convert it to a string and send that instead. – Some programmer dude Mar 30 '13 at 16:38
  • @Joachim Pileborg: That could be one of the use cases. I need to replicate some java code that uses BigInteger and uses the toByteArray() method. I was expecting such functionality from cpp_int. I know GMP can do it. Perhaps using gmp_int is helpful, when accessing the backend. – NFRCR Mar 30 '13 at 16:41
  • I think you can use cpp_int::convert_to<>() function or cpp_int::str() function. http://www.boost.org/doc/libs/1_53_0/libs/multiprecision/doc/html/boost_multiprecision/ref/number.html convert_to() function internal use boost::lexical_cast. If your want (array) type have stream operator, you can use this approach. However, convert_to() function return value is not direct internal value. – Akira Takahashi Mar 31 '13 at 02:06

2 Answers2

2

This is undocument way. cpp_int's backend have limbs() member function. This function return internal byte array value.

#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>

namespace mp = boost::multiprecision;

int main()
{
    mp::cpp_int x("11111111112222222222333333333344444444445555555555");

    std::size_t size = x.backend().size();
    mp::limb_type* p = x.backend().limbs();

    for (std::size_t i = 0; i < size; ++i) {
        std::cout << *p << std::endl;
        ++p;
    }
}

result:

10517083452262317283
8115000988553056298
32652620859
Akira Takahashi
  • 2,912
  • 22
  • 107
  • When I run your program I get a different result. Is this due to different endians (Win32 here)?: 2369518819 2448699309 1789268010 1889420903 2587849787 7 – PeteUK Jun 25 '13 at 10:07
  • Why are there only decimal digits? Is the number stored inside cpp_int is decimal encoded internally? Isn't it stored as 32 bit, or 64 bit words? – Arty Sep 26 '14 at 16:01
  • @PeteUK sizeof(mp::limb_type), and the number of limbs, will differ whether using a 32-bit or 64-bit compiler, which leads to potentially different results on different platforms – James Beilby Apr 25 '16 at 17:05
  • Limbs are not bytes nor arrays of bytes. Limbs are 32-bit or 64-bit integers depending whenever the compiler support 128-bit type. You can cast them to array of bytes and byte-swap them if needed. – Paweł Bylica Aug 30 '16 at 19:33
2

This is the documented way of exporting and importing the underlying limb data of a cpp_int (and cpp_float). From the example given in the docs, trimmed down for the specific question:

#include <boost/multiprecision/cpp_int.hpp>
#include <vector>

using boost::multiprecision::cpp_int;

cpp_int i{"2837498273489289734982739482398426938568923658926938478923748"};

// export into 8-bit unsigned values, most significant bit first:
std::vector<unsigned char> bytes;

export_bits(i, std::back_inserter(bytes), 8);

This mechanism is quite flexible, as you can save the bytes into other integral types (just remember to specify the number of bits per array element), which in turn works with import_bits, too, if you need to restore a cpp_int from the deserialized sequence.

lubgr
  • 37,368
  • 3
  • 66
  • 117