-1

First of all, I am aware that what I am trying to do might be outside the C standard.

I'd like to know if it is possible to make a uint4_t/int4_t or uint128_t/int128_t type in C.

I know I could do this using bitshifts and complex functions, but can I do it without those?

3 Answers3

3

You can use bitfields within a structure to get fields narrower than a uint8_t, but, the base datatype they're stored in will not be any smaller.

struct SmallInt
{
   unsigned int a : 4;
};

will give you a structure with a member called a that is 4 bits wide.

Colin
  • 3,394
  • 1
  • 21
  • 29
  • 4
    This isn't standard C. You can't portably use `uint8_t` for bit-fields. – Lundin Dec 21 '16 at 14:38
  • 2
    Here is a standard reference for that: `C11 6.7.2.1 5` *"A bit-field shall have a type that is a qualified or unqualified version of `_Bool`, `signed int`, `unsigned int`, or some other implementation-defined type. It is implementation-defined whether atomic types are permitted."* This restriction was lifted in C++: `C++14 9.6 3` *"... A bit-field shall have integral or enumeration type ..."*. – HolyBlackCat Dec 21 '16 at 14:54
  • @Lundin Thanks, Both, Updated. – Colin Dec 21 '16 at 15:01
  • @Colin__s if I pack this structure, will it take up 4 bits? –  Dec 21 '16 at 15:29
  • @MarkYisri, no, it will take up at minimum the `sizeof(unsigned int)`. `sizeof(char)` is 1 due to the standard, and char bits is at minimum 8 due to the standard. – Colin Dec 21 '16 at 15:30
  • @Colin__s then what is the use of a bitfield? –  Dec 21 '16 at 15:31
  • @MarkYisri you could pack 8 * 4 bit values inside one 32 bit value without having to do the bit twiddling yourself. – Colin Dec 21 '16 at 15:32
  • @Colin__s and then do a bitmask to ensure only the correct 4 bits are visible? –  Dec 21 '16 at 15:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/131169/discussion-between-mark-yisri-and-colin-s). –  Dec 21 '16 at 15:33
  • This answer does not address OP's 1st half question "Is there a general way in C to make a number greater than 64 bits ...?". Curious that this answer is accepted. – chux - Reinstate Monica Dec 21 '16 at 17:27
  • @chux I accepted it because he says that you cannot make it smaller in his answer. "_but, the base datatype they're stored in will not be any smaller._" –  Dec 22 '16 at 12:03
  • @MarkYisri Hmm. "but, the base datatype they're stored in will not be any smaller." does not address the issue to "Is there a general way in C to make a number greater than 64 bits ...?" Oh, well. – chux - Reinstate Monica Dec 22 '16 at 15:18
  • @chux my question also has "_or smaller than 8 bits?_" –  Dec 23 '16 at 11:39
3

Individual storage units (bytes) are no less than CHAR_BITS bits wide1; even if you create a struct with a single 4-bit bitfield, the associated object will always take up a full storage unit.

There are multiple precision libraries such as GMP that allow you to work with values that can't fit into 32 or 64 bits. Might want to check them out.


  1. 8 bits minimum, but may be wider.

abelenky
  • 63,815
  • 23
  • 109
  • 159
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • can GMP do 4 bits? –  Dec 21 '16 at 15:28
  • @MarkYisri: It can certainly represent *values* that are at most 4 bits wide, but so can the native integer types. Again, no *object* can be less than 8 bits wide. MP libraries are geared more for working with values that *can't* fit in the native types. – John Bode Dec 21 '16 at 15:41
2

In practice, if you want very wide numbers (but that is not specified in standard C11) you probably want to use some arbitrary-precision arithmetic external library (a.k.a. bignums). I recommend using GMPlib.

In some cases, for tiny ranges of numbers, you might use bitfields inside struct to have tiny integers. Practically speaking, they can be costly (the compiler would emit shift and bitmask instructions to deal with them).

See also this answer mentioning __int128_t as an extension in some compilers.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547