-
Notifications
You must be signed in to change notification settings - Fork 0
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)
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).
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++.
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).
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.
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.
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).