The good news is that signed and unsigned integers have the same byte representation when it comes to endianness - the only difference is how those bytes are interpreted. Let's explore this in detail:
Here's a program that demonstrates how signed and unsigned integers are handled:
#include <iostream>
#include <iomanip>
#include "SDL.h"
void PrintBytes(const char* Label,
const void* Data,
size_t Size) {
auto* Bytes = static_cast<const uint8_t*>(
Data);
std::cout << Label << ": ";
for (size_t i = 0; i < Size; ++i) {
std::cout << std::hex << std::setw(2)
<< std::setfill('0')
<< static_cast<int>(Bytes[i]) << " ";
}
std::cout << std::dec << '\n';
}
int main() {
// Compare signed and unsigned representations
int32_t Signed{-42};
uint32_t Unsigned{static_cast<uint32_t>(-42)};
PrintBytes("Signed ", &Signed,
sizeof(Signed));
PrintBytes("Unsigned", &Unsigned,
sizeof(Unsigned));
// Write both to file
SDL_RWops* Handle{
SDL_RWFromFile("numbers.bin", "wb")};
if (!Handle) { return 1; }
SDL_WriteLE32(Handle, Unsigned);
SDL_RWseek(Handle, 0, RW_SEEK_SET);
// Read back as both signed and unsigned
int32_t ReadSigned{
static_cast<int32_t>(SDL_ReadLE32(Handle))};
SDL_RWseek(Handle, 0, RW_SEEK_SET);
uint32_t ReadUnsigned{SDL_ReadLE32(Handle)};
SDL_RWclose(Handle);
std::cout << "\nRead back values:\n"
<< "As Signed : " << ReadSigned << '\n'
<< "As Unsigned: " << ReadUnsigned << '\n';
}
Signed : d6 ff ff ff
Unsigned: d6 ff ff ff
Read back values:
As Signed : -42
As Unsigned: 4294967254
SDL_WriteLE32()
, SDL_ReadLE32()
, etc.) treat all integers as unsignedHere's an example showing how to write a helper function that handles both types:
#include <iostream>
#include "SDL.h"
template <typename T>
void WriteNumber(SDL_RWops* Handle, T Value) {
if constexpr (sizeof(T) == 2) {
SDL_WriteLE16(Handle,
static_cast<Uint16>(Value));
} else if constexpr (sizeof(T) == 4) {
SDL_WriteLE32(Handle,
static_cast<Uint32>(Value));
} else if constexpr (sizeof(T) == 8) {
SDL_WriteLE64(Handle,
static_cast<Uint64>(Value));
}
}
int main() {
SDL_RWops* Handle{
SDL_RWFromFile("numbers.bin", "wb")};
if (!Handle) { return 1; }
// Works with both signed and unsigned
WriteNumber(Handle, int32_t{-42});
WriteNumber(Handle, uint32_t{42});
WriteNumber(Handle, int16_t{-12345});
WriteNumber(Handle, uint64_t{9999});
SDL_RWclose(Handle);
}
Remember:
Answers to questions are automatically generated and may not have been reviewed.
Learn how to handle byte order in using SDL's endianness functions