Help With C++ Project!

Heres the question!

Bit Manipulation Lab
7) Allow the user to input 8 integer values all between 0 and 15 inclusive. Store these 4 values into a single 32 bit integer named "packit" Allow the user to choose which of the 8 integers they wish to recover from "packit". An input of 1 will recover the first value input, a 2 the second, a 3 the third, etc. Use only bit manipulations to store and recover the values. Optionally you may also output the value in its binary format in addition to its base 10 value.
some compilers work ok with signed, but you should generally use unsigned with bit stuff.

What have you done so far?
My teacher gives all his projects at the same time so we have not learned bit manipulation yet, I just wanted to get a head start on it if someone could point me in the right direction
Ok. Hopefully I got all the code stuff right. If not, hopefully the concept is clear anyway..

bitwise functions:
>> shift 1 bit. so 8 >> 1 is 4.
<< shift the other way, 4 << 1 is 8.
| or each bit of 2 integers. Not to be confused with ||, which ors the entire value of the integers together as Booleans (not zero = true).
& bit and (&& is Boolean as above)
^ xor
~ not (I think?)
there might be a nand in there somewhere. I forget.

so say you had a 32 bit unsigned int:
uint32_t x = 0x 12 34 56 78 //broken up hex value for the example. not code.

now say you wanted to put 11 decimal (0x0B) into it at the highest order byte .

one way to do that is to put 11 into another int and shift it:

uint32_t y = 11;
y << 24;
should produce
0B 00 00 00

now, you can clear the high bits of X:
x &= 0x00FFFFFF which retains what was in the lower 3 bytes and zeros out the high 4th byte. x is now 00 34 56 78

and finally you can OR them to assign (or just add, like a normal person)
x |= y; //x is now 0B 34 56 78

you probably want a full set of clear constants defined, 00 ff ff ff, ff 00 ff ff, ff ff ff 00, etc... its usually best to do a bunch of house keeping up front so your code is really clean after when doing this stuff.



By the way, this bit stuff is almost always silly. A lot of programmers get fired up and excited to get to use hex or binary, but its just shooting yourself in the foot, you do a lot of extra work more often than not.

enum
{
firstbyte = 0,secondbyte,thirdbyte,fourthbyte, emax
};

union u
{
uint32_t x;
unint8_t c[emax];
};

u var;
var.x = 0;
var.c[firstbyte] = 11;
var.x ... is now 0x0B 00 00 00 00
var.c[secondbyte] = 12;
var.x .... is now 0x 0B 0C 00 00

all packed up nice and clean, without all the mess.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# include <limits>
# include <iostream>
# include <bitset>

static constexpr std::uint32_t nybble_mask(int k)
{ return 0xF << (4 * k); }

static constexpr std::uint32_t pack_nybble(std::uint32_t n, int k, std::uint8_t val)
{ return (n &= ~nybble_mask(k)) | (val << (4 * k)); }
static constexpr std::uint32_t unpack_nybble(std::uint32_t n, int k)
{ return (n & nybble_mask(k)) >> (4 * k); }

int main(int, char**) {
  std::uint32_t packed{}, nybble{};
  for (int i = 0; i < 8 && std::cin >> nybble; ++i)
    packed = pack_nybble(packed, i, nybble);

  std::cout << "value: " << std::bitset<32>{packed} << "\n";

  for (int i = 0; i < 8; ++i)
    std::cout << "integer " << i << ": " << unpack_nybble(packed, i) << "\n";
}

http://coliru.stacked-crooked.com/a/e4a6dbc1afec9765

This didn't work for me, is there any other way to do this? I only know very simple code
Allow the user to input 8 integer values all between 0 and 15 inclusive. Store these 4 values into a single 32 bit integer

Ask the prof to clarify. Is it 8 values or 4?
Here's a C++98 version of the same program
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# include <stdint.h>
# include <iostream>
# include <bitset>
# include <iomanip>

static uint32_t nybble_mask(int k)
{ return 0xF << (4 * k); }
static uint32_t pack_nybble(uint32_t n, int k, uint8_t val)
{ return (n &= ~nybble_mask(k)) | (val << (4 * k)); }
static uint32_t unpack_nybble(uint32_t n, int k)
{ return (n & nybble_mask(k)) >> (4 * k); }

int main(int, char**) {
  uint32_t packed = 0, nybble = 0;
  for (int i = 0; i < 8 && std::cin >> nybble; ++i)
    packed = pack_nybble(packed, i, nybble);

  std::cout << "value: " << std::bitset<32>(packed).to_string() << "\n";

  for (int i = 0; i < 8; ++i)
    std::cout << "integer " << i << ": " << unpack_nybble(packed, i) << "\n";
}

http://coliru.stacked-crooked.com/a/bd23325f864d9192
Last edited on
Topic archived. No new replies allowed.