gcc
4.4 seems to be the first version when they added int128_t
. I need to use bit shifting and I have run out of room for some bit fields.
Edit: It might be because I'm on a 32-bit computer, there's no way to have it for a 32-bit computer (Intel Atom), is there? I wouldn't care if it generated tricky slow machine code if I would work as expected with bit shifting.
Software. In the same way that compilers emulate e.g. 64-bit integer arithmetic on architectures with register sizes less than 64 bits, some compilers also support 128-bit integer arithmetic. For example, the GCC C compiler 4.6 and later has a 128-bit integer type __int128 for some architectures.
The 128-bit data type can handle up to 31 significant digits (compared to 17 handled by the 64-bit long double). However, while this data type can store numbers with more precision than the 64-bit data type, it does not store numbers of greater magnitude.
As an extension the integer scalar type __int128 is supported for targets which have an integer mode wide enough to hold 128 bits. Simply write __int128 for a signed 128-bit integer, or unsigned __int128 for an unsigned 128-bit integer.
I'm pretty sure that __int128_t
is available on earlier versions of gcc. Just checked on 4.2.1 and FreeBSD and sizeof(__int128_t)
gives 16.
You could also use a library. This would have the advantage that it is portable (regarding platform and compiler) and you could easily switch to even bigger datatype. One I could recommend is gmp (even if its intention is not to handle bitwidth x, but variable as big as you want).
Bit shifting is very easy in any arbitrary number of bits. Just remember to shift the overflowed bits to the next limb. That's all
typedef struct {
int64_t high;
uint64_t low;
} int128_t;
int128_t shift_left(int128_t v, unsigned shiftcount)
{
int128_t result;
result.high = (v.high << shiftcount) | (v.low >> (64 - shiftcount));
result.low = v.low << shiftcount;
return result;
}
Similar for shift right
int128_t shift_right(int128_t v, unsigned shiftcount)
{
int128_t result;
result.low = (v.low >> shiftcount) | (v.high << (64 - shiftcount));
result.high = v.high >> shiftcount;
return result;
}
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