C++ 128/256-bit fixed size integer types
Asked Answered
E

5

20

I was wondering if any fellow SO's could recommend a good light-weight fixed size integer type (128-bit or even 256-bit, possibly even template parametrized) library.

I've had a look at GMP and co, they care great, yet are a bit too large for my purposes, I'm interested in simple header only solutions at this point. Performance is important and the target architecture will be x86 and x86-64, also a reasonable license (aka nothing GPL or LGPL).

Erubescence answered 9/3, 2011 at 7:51 Comment(3)
Haven't seen those, but it shouldn't be too hard to write it on your own? (and as a bonus, you will have no licencing problems)Electrostatic
Also noting this question: stackoverflow.com/questions/1188939/…Nebuchadnezzar
Related: Clang supports C23 typedef unsigned _BitInt(256) u256; as an extension for C++. See Is there a 256-bit integer type?Dragonfly
Z
11

The Boost library has data types as part of multiprecision library, for types ranging from 128 to 1024 bits.

#include <boost/multiprecision/cpp_int.hpp>

using namespace boost::multiprecision;

int128_t mySignedInt128 = -1;
uint128_t myUnsignedInt128 = 2;
int256_t mySignedInt256 = -3;
uint256_t myUnsignedInt256 = 4;
int512_t mySignedInt512 = -5;
uint512_t myUnsignedInt512 = 6;
int1024_t mySignedInt1024 = -7;
uint1024_t myUnsignedInt1024 = 8;
Zoi answered 25/2, 2015 at 2:29 Comment(1)
Tried it. Far too slow. I used it for some GF(2) polynomial operations. 256 bit type is ~270 times slower than doing the exact same calculation with native 64 bit integers.Goles
B
2

The Xint library is currently under review to become part of Boost. Although it is discussed rather controversially and the outcome of the review is not clear yet, the library fulfills some of your requirements:

  • header only
  • reasonable license

One of the points that are discussed during the review is performance though. If accepted as an official Boost library, I expect performance issues to be addressed promptly.

So I would give it a try: Code, Documentation.

Benzol answered 9/3, 2011 at 10:0 Comment(1)
I just read your comment to Seve-o's answer where you clarify your requirements. My take-away from the discussion on the ML is that what you look for does not exist yet. In my opinion Xint will be accepted and a version 2 might contain what you look for in terms of performance. It already has everything you need in terms of functionality.Benzol
A
2

You can use boost (Tested on 1.76.0):

#include <cstdint>
#include <iomanip>
#include <iostream>

#include <boost/multiprecision/cpp_int.hpp>

using uint512_t  = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512,  512,  boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;
using uint1024_t = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<1024, 1024, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;
using uint2048_t = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<2048, 2048, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;
using uint4096_t = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<4096, 4096, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;
using uint8192_t = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<8192, 8192, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;

int main()
{
  uint8192_t u(2U);

  for (int64_t i = 0; i < 4096 - 1; i++) {
      u *= 2;
  }

  std::cout << u << std::endl;
} 
Amidase answered 20/8, 2021 at 19:54 Comment(0)
G
1

Depending on your requirements, the STL class bitset might fit your needs. It responds to all the bit-manipulation operators that integer types do (<<,| etc.), but unfortunately not to arithmetic operators like + or *. Its size is fixed at compile time via a template parameter. Another unfortunate thing is that the API provides no way to get at the underlying binary representation (e.g. for streaming it), which might seriously limit its usefulness.

(I know this is an old question, but this answer might help others.)

Goren answered 14/7, 2014 at 2:40 Comment(0)
N
-1

Some native 128-bit types are available on certain platforms, you tend to be limited by the architecture. For example __m128 is available for SSE2?

http://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx

Also listed as __int128 in this ABI:

http://www.x86-64.org/documentation/abi-0.99.pdf

However the preferred naming of uint128_t and uint256_t can be found in SHOGUN, a "large scale machine learning toolbox with focus on especially Support Vector Machines (SVM)"

http://www.shogun-toolbox.org/doc/index.html

Nebuchadnezzar answered 9/3, 2011 at 9:20 Comment(1)
__m128i is a packed vector of integers elements. SSE/AVX supports packed integer add/sub with element widths from 8b to 64b, but not 128b. Of course, boolean operations with no carry between bits (like AND/OR/XOR) Just Work. For arbitrary precision math, SSE doesn't provide a carry vector so it's generally faster to use integer add / adc than to hack something up with SSE.Dragonfly

© 2022 - 2024 — McMap. All rights reserved.