diff options
| author | Chris Boesch <chrboesch@noreply.codeberg.org> | 2026-04-03 13:35:56 +0200 |
|---|---|---|
| committer | Chris Boesch <chrboesch@noreply.codeberg.org> | 2026-04-03 13:35:56 +0200 |
| commit | e0259f43a726f61da14686de802021fcdb9aacd0 (patch) | |
| tree | 57359102e5e898289b91ada2d65ca742ec118c8b /exercises/115_packed2.zig | |
| parent | ffde357f303e7459a12cfe4b785ae9e8ef9ebe30 (diff) | |
Insert space for additional async exercises
Diffstat (limited to 'exercises/115_packed2.zig')
| -rw-r--r-- | exercises/115_packed2.zig | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/exercises/115_packed2.zig b/exercises/115_packed2.zig new file mode 100644 index 0000000..2b6b558 --- /dev/null +++ b/exercises/115_packed2.zig @@ -0,0 +1,78 @@ +// +// We've already learned about switch statements in exercises 030, 031 and 108. +// They also work with packed containers: + +const S = packed struct(u2) { + a: bool, + b: i1, +}; + +// Try to make it compile without adding an `else` prong! + +comptime { + const s: S = .{ .a = true, .b = -1 }; + switch (s) { + .{ .a = true, .b = -1 } => {}, // ok! + .{ .a = true, .b = ??? }, + .{ .a = ???, .b = 0 }, + .{ .a = ???, .b = ??? }, + => @compileError("We don't want to end up here!"), + } +} + +// As we can see, switching on packed structs is pretty straightforward. +// When switching on packed unions however, we'll realize that a packed +// union never keeps track of its active tag, not even in debug mode! This +// means that packed unions compare solely by their bit pattern (again, just +// like integers). + +const U = packed union(u2) { + a: u2, + b: i2, +}; + +// Find and remove the duplicate case! + +comptime { + const u: U = .{ .a = 3 }; + switch (u) { + .{ .a = 3 } => {}, // ok! + .{ .a = 2 }, + .{ .b = 1 }, + .{ .b = -1 }, + .{ .a = 0 }, + => @compileError("We don't want to end up here!"), + } +} + +// Since packed unions don't have the concept of an active tag, it's always legal +// to access any of their fields. This can be useful to view the same data from +// different perspectives seamlessly. +// +// Try to make the float below negative: + +/// IEEE 754 half precision float +const Float = packed union(u16) { + value: f16, + bits: packed struct(u16) { + mantissa: u10, + exponent: u5, + sign: u1, + }, +}; + +pub fn main() void { + // Reminder: if the sign bit of a float is set, the number is negative! + + var number: Float = .{ .value = 2.34 }; + number.bits.??? = ???; + if (number.value != -2.34) { + std.debug.print("Make it negative!\n", .{}); + } +} + +// This concludes our introduction to packed containers. The next time you need +// control over individual bits, keep them in mind as a potent alternative! +// + +const std = @import("std"); |
