Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to do 128-bit shifts on gcc <4.4?

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.

like image 536
Roman A. Taycher Avatar asked Apr 07 '11 05:04

Roman A. Taycher


People also ask

Does C have 128-bit integers?

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.

How many digits is a 128-bit number?

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.

What is int128_t?

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.


3 Answers

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.

like image 182
janm Avatar answered Sep 20 '22 04:09

janm


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).

like image 20
flolo Avatar answered Sep 22 '22 04:09

flolo


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;
}
like image 45
phuclv Avatar answered Sep 21 '22 04:09

phuclv