#Bitcasting a byte

1 messages · Page 1 of 1 (latest)

cold mortar
#

I'm trying to figure out what's going on here. I was under the impression that in the following program, the last field would contain the value 6 since it aligns with the lower 6 bits of the byte, but that doesn't seem to be the case.

const std = @import("std");
const mem = std.mem;
const debug = std.debug;

pub fn main() !void {
    const num: u8 = 6;
    const small = @bitCast(Small, num);
    debug.print("\nfirst: {b}, last: {b}\n", .{ small.first, small.last });
    debug.print("num:   {b}\n", .{ num });
    debug.print("small: {b}\n", .{ mem.toBytes(small)[0] });
}

pub const Small = packed struct {
    first: u2,
    last: u6,
};
first: 10, last: 1
num:   110
small: 110
fair magnet
#

first is the first 2 bits, last is the last 6 bits

#

packed struct fields are laid out least to most significant

astral yacht
#

Yeah packed struct fields are laid out in little-endian order

#

(bit order, not byte order - the fields are packed into an integer whose byte order is the native endian)

cold mortar
#

Oh I thought bit order was always big endian okay

astral yacht
#

It's always little endian

#

Which is useful since adding more fields to the end doesn't change the bits that the first fields correspond to

#

So eg. adding more boolean flags doesn't change the integer representation of the existing ones

fair magnet
#

and the lower bits are usually the bits you want to twiddle

cold mortar
#

I guess I'm so used to seeing bits represented as big endian when being printed I assumed it was the same in the CPU

#

Well thanks!

cold mortar
#

Does this change based on the endiness of the CPU?

#

Also does it change if a bitfield crosses the byte boundary?

astral yacht
#

The byte endian changes based on the CPU but the bit endian does not