storing two nibble in a byte

Mar 23, 2017 at 10:53am
hi friends,
I am at novice level of learning programming.I am involved in a project which requires to store two nibbles in a byte .how to do this
Mar 23, 2017 at 11:29am
its called a bit-field and looks like this..

struct nibs
{
unsigned char a:4; //4 bits
unsigned char b:4;
};

you can also write a class to manually do logical operations to handle this if you need something odd.
Last edited on Mar 23, 2017 at 11:31am
Mar 23, 2017 at 11:32am
Read up on the bitwise operations.

1
2
3
4
unsigned char nibble1 = 0xF;
unsigned char nibble2 = 0x5;
unsigned char byte = nibble1 | (nibble2 << 4);
std::cout << std::hex << static_cast<int>(byte); // 5F 
Mar 23, 2017 at 4:22pm
I said logical not bitwise, I do things like that sometimes, sorry.
Also, a warning... don't C++ify the structs with methods. I think that will break things. Use the struct as a POD/Base type in a class, that is fine, but don't make IT the object.

I was thinking that if you had to ask, you might not know how to use what I said.

int main(int argc, char** argv)
{
nibs x;
cout << sizeof(x) << endl;
x.a = 10;
x.b = 11;
unsigned char * cp = (unsigned char*)(&x);
printf("%X\n", cp[0]); //stubborn am I.
}

prints
1
BA

or, in english, CP is a pointer to a byte that has 2 nibbles :)
Note that 'a' is the low order bits, and 'b' is the high order bits. But it will print backwards in hex, because of this, though logically a is first. Right?

You can also avoid the pointer mess with a union...

union u
{
nibs n;
unsigned char c;
};

u x;
x.n.a = 10;
x.n.b = 11;
/// x.c is your byte, without the pointer magic. it is "cp[0]" above, conceptually.

I *think* (wow, this has been a long while) that intel assembler can directly access nibbles via al and ah half registers? Not 100% sure, but if I recall it right you have eax (32?), ax (16), a (8), and al and ah (4 bits each). A couple of lines of assembler could do this, if you wanted to really go off on a tangent!





Last edited on Mar 23, 2017 at 4:57pm
Mar 24, 2017 at 4:34am
how to do this part in c
std::cout << std::hex << static_cast<int>(byte);
Last edited on Mar 24, 2017 at 4:34am
Mar 24, 2017 at 4:57am
i Got this one.it worked..thanks alot for the help.
printf("%.4x",a);
Mar 24, 2017 at 5:07am
@Jonnin, the packing of bitfields isn't guaranteed by the standard. In other words, there's no guarantee that this structure will occupy one byte.

Says 12.2.4.1 [class.bit]:
... Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. ...

http://eel.is/c++draft/class.bit#1

Bitfields are useless (at least for my purposes) thanks to that passage. It's either bitfields or unions (since reading the non-active variant member causes undefined behavior) which have my vote for the least-useful core language feature. I digress.

It's fine to make class types with bit-field members non-POD as long as you don't later assume they're not (although that assumption is quite usual for such a class).
Last edited on Mar 24, 2017 at 5:10am
Mar 24, 2017 at 12:19pm
Right. I agree, but in practice, I have yet to find this theoretical compiler that does not work on the above code as I laid it out. Someone here probably knows of one, I don't use that many different compilers.

Honestly, the idea of a nibble is useless to me unless packing something up for an embedded system that wants 2 per byte in its communications protocol. There are not a whole lot of those left in the world either.

If your compiler works as above, its probably the cleanest way to do the nibble thing. If not, you can write a bunch of shifting and /or code or as I said, a handful of assembly lines gets you there non-portable style. Its easy to test if it works. Run it, and see if your struct is size 1 :) If not, you need to do something else.


Mar 24, 2017 at 12:44pm
if I recall it right you have eax (32?), ax (16), a (8), and al and ah (4 bits each).
Aren't al and ah the low byte and high byte of ax? I don't recall 4-bit direct access on x86, but like you, it's been a looooonnng time.

Trivia: HP used a 4-bit processor in it's calculators for a long time. Each address referred to a 4-bit nibble. They used this type of processor (or an emulator of it) right up through the HP-50g which was recently discontinued. The HP-12C, which has been in continuous production for something like 30 years, still uses it, although via an emulator.
https://en.wikipedia.org/wiki/HP_Saturn
Mar 24, 2017 at 1:38pm
:) I use the 11c, and have a new in the box backup if it ever dies (its been going since at least 1988 though). I didn't know that about it.



Mar 24, 2017 at 6:58pm
Damn! A new-in-box 11C might be more valuable than you think. If you ever want to sell it, pop over to hpmuseum.org and post it in the classified section. That's where all the HP calculator nerds hang out :)
Mar 25, 2017 at 1:09am
I don't think any amount would part me with that thing. You can't get a decent RPN calculator anymore. I could let the 15 go, but never an 11. They used to buy my dad a new one ever year or and he could keep the old one as devalued/destroyed equipment. So he brought them home. So I now have 2 11s and a 15, + my own GX or whatever it was with the 3-d plotting from the 90s. All but the one 11 are effectively new. Maybe I can retire now lol, sitting on a gold mine..


Topic archived. No new replies allowed.