I tried to add bits to an __int128 (using clang compiler and 64-bit system), but failed.
__int128 x = 0; //DECLARING AND INITIALIZING X
x |= ((static_cast<__int128>(1)) << 95); //ADDING A '1' TO 95th BIT (from right)
std::cerr<< std::bitset<100>(x) << std::endl; //PRINTING BITSET
prints:
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
I know there are short forms I can use for unsigned int or long long int, such as
(1u << 15) or (1LL << 15), but I haven't found any 128-bit equivalent.
What do I need to do make this work?
The int128 type defines a signed 128-bit integer. The API is meant to mimic an intrinsic integer type as closely as possible, so that any forthcoming int128_t can be a drop-in replacement. The int128 type supports the following: Implicit conversion from signed integral types and unsigned types narrower than 128 bits.
Simply write __int128 for a signed 128-bit integer, or unsigned __int128 for an unsigned 128-bit integer. There is no support in GCC for expressing an integer constant of type __int128 for targets with long long integer less than 128 bits wide.
If we use braces std::bitset<100>{x}
instead of parentheses std::bitset<100>(x)
, the program fails to compile because of a narrowing conversion:
error: non-constant-expression cannot be narrowed from type
'__int128'
to'unsigned long long'
in initializer list[-Wc++11-narrowing]
What's happening here is the __int128
is working correctly, but the conversion to std::bitset
is incorrect. You'll have to split the __int128
into 64-bit chunks:
std::bitset<100> hi{static_cast<unsigned long long>(x >> 64)},
lo{static_cast<unsigned long long>(x)},
bits{(hi << 64) | lo};
std::cout << bits << '\n';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With