1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | // This is not working code. This is just notes in the form of a C file, for tidiness.
// .current_byte: 00000000₂
write_bits(&writer, 0x05, 3); // 00000101₂
// ‾‾‾
// Inside write_bits(…):
// When reading bits from our parameter ('byte'), we take from the least significant
// (rightmost) side. When writing to the file (or to .current_byte), we write to the
// most significant (leftmost) side.
//
// Need to get our 3 bits to the most significant (leftmost) side.
// byte ============= 00000101₂ == 0x05
// byte << 5 ======== 10100000₂
// byte << (8 - 3) == 10100000₂
// ↑
// num_bits_to_write
//
// New .current_byte:
//
// .current_byte | byte << (8 - 3) == 00000000₂ | 10100000₂ == 10100000₂
// .current_byte == 10100000₂
write_bits(&writer, 0xf3, 3); // 00000101₂
// Inside write_bits(…):
// .current_byte == 10100000₂ // 0xa0
// .byte ========== 11110011₂ // 0xf3
//
// We will start with an "okay" way
//
// We need to shift bits of 'byte' to the left... not all the way to the left, but to the
// position where they will be when written to .current_byte.
//
// .current_byte == 10100000₂ // 0xa0
// ─┬─
// new bits go here
//
// byte ========== 11110011₂ // 0xf3
// ┌─┘ ┌─┘
// byte << 2 ===== 11001100₂ // 0xcc
//
// How did we know it should be shifted by two?
//
// byte << (8 - num_bits_to_write - bits_written_to_current_byte_so_far)
//
// WRONG WAY:
// byte << 2 | .current_byte == 11001100₂ | 10100000₂ // WRONG!!!
// == 11101100₂ // WRONG!!!
//
// Problem is that we did not clear extra bits from the most significant (leftmost)
// side of byte.
//
// BETTER: Use a bit mask (00011002₂) to select only the bits from 'byte' that
// you want to set.
//
// byte << 2 & 00011100₂ | .current_byte == (11110011₂ << 2) & 00011100₂ | 10100000₂
// == (11001100₂ & 00011100₂) | 10100000₂
// == 00001100₂ | 10100000₂
// .current_byte ========================== 10101100₂
//
// Let's improve that calculation. How did we get that bit mask?
//
// Easier to do the masking before the bit shift.
//
// byte == 11110011₂
// byte & 00000111₂ == 00000011₂ // only the bits we want to keep
// ‾‾‾
// byte & create_string_of_1s_at_right(3) ================== 00000011₂
// byte & create_string_of_1s_at_right(num_bits_to_write) == 00000011₂
//
// I am not suggesting that you include your warmup.c in your build (Makefile) for HW18.
// I'm just saying that you can use that same logic from the warmup for this.
//
// byte && 00000111₂ << 2 | .current_byte == 11110011₂ & 00000111₂ << 2 | 10100000₂
// == 00000011₂ << 2 | 10100000₂
// ‾‾‾
// == 00001100₂ | 10100000₂
// ‾‾‾
// .current_byte =========================== 10101100₂
/* vim: set tabstop=4 shiftwidth=4 fileencoding=utf-8 expandtab: */
|
© Copyright 2021 Alexander J. Quinn This content is protected and may not be shared, uploaded, or distributed.