Skip to content

24bit integers

ZERICO2005 edited this page Jul 3, 2024 · 4 revisions

24bit integers

24bit integers aren't natively supported on most CPU's. This article lists a few ways to implement 24bit integers on non-24bit platforms.

If none of these implementations work for your project, you can always refactor the code to use 16bit/32bit types instead.

_BitInt(24) and _ExtInt(24)

_BitInt(24) and _ExtInt(24) are the easiest to implement, and can be done with a simple typedef unsigned _BitInt(24) uint24_t.

Pros:

  • Can be Signed and Unsigned.
  • Reads/Writes exactly 3bytes.

Cons:

  • Relies on C23 and/or compiler extensions.
  • Padded to 4 bytes (Not packed).

int24_t C++ class

class int24_t {
    private:
        uint8_t bytes[3];
};

Due to operator overloading and a few other features of C++, creating an int24_t class is probably the most accurate int24_t you can get on non-24bit platforms. It is exactly 3 bytes packed, and can be almost used like a normal integer. However, there are a few caveats related to casting, since a class can't be "signed" or "unsigned".

Pros:

  • Exactly 3 bytes packed.

Cons:

  • Higher complexity.
  • A C++ class can't be "signed" or "unsigned".
  • Not every C program can be compiled as C++.

typedef int32_t int24_t

A plain and simple typedef int32_t int24_t may work depending on the program was written. If a value overflows, or packed values are read/written to, the program can crash/segfault.

Pros:

  • Simple to implement

Cons:

  • Reads/Writes 4bytes instead of 3bytes.
  • Padded to 4 bytes (Not packed).

int24_t struct

typedef struct int24_t {
    uint8_t bytes[3];
} int24_t;

A simple struct can have a packed size of 3 bytes. The problem with structs however is that you can't directly perform operations on them like you would with a regular integer. For example, uint24_t x = y + a * b (infix notation) would have to be done as x = ADD_U24(y, MUL_U24(a, b)) (function notation), which is not as readable.

Pros:

  • Exactly 3 bytes packed (Double check with your compiler).

Cons:

  • Can't be used with infix notation.
  • Casts are required for operations.
  • Structs can't be "signed" or "unsigned".
  • Individual bytes could be accessed directly.

bitfields

typedef struct {
    int32_t value : 24;
} int24_t;

You can also try using bitfields. Values written to them will be converted to a 24bit integer. However, they are not packed as the bitfields access a 32bit integer under the hood.

C++ struct

structs in C++ have a few more features than structs in C. Although I am not sure if they are better suited for a 24bit integer implementation compared to a C++ class.

Pros:

  • Values should be truncated to 24bits.

Cons:

  • Might be dependent on compiler extensions.
  • Padded to 4 bytes (Not packed).