Go Down

### Topic: 2 & 3 Bit Numbers (Read 2386 times)previous topic - next topic

#### flocked

##### Oct 03, 2013, 11:29 pm
Hi,

Is it possible to save 2 & 3 bit values? I don't want to use integers, because they are to big…

I know that I can use an integer and shift the bit values to read them. It would work for the 2 bit values and I could save up to 4 numbers in a integer. But what should I do with the 3 bit values? They don't really fit in a 8 bit integer. Is there really no better way in saving 3 bit values?

Thanks1

Oh and I found this code:
Code: [Select]
`   struct Cell {      int a : 2;      int b : 2;      int c : 2;      int d : 2;   };`
Would this be an abstraction of 4x two bit values for 1 integer? or would it save 4 integers.

#### Tom Carpenter

#1
##### Oct 03, 2013, 11:33 pm
An int is 16 bits, a byte is 8.

Your struct would work for storing 4 x 2bit variables in a byte, just remember that the compiler will use bit shifts to access them, so while it will reduce RAM consumption by a factor of 4, it will increase the time it takes to do calculations using them and increase Flash usage.
~Tom~

#### MarkT

#2
##### Oct 03, 2013, 11:40 pm
Those struct fields are called bit fields and they are exactly what you are looking for.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

#### Tom Carpenter

#3
##### Oct 03, 2013, 11:48 pm
Also remember that bitfield have signedness.
In otherwords, your two bit variable declared as a signed int can take the values:
-2, -1, 0 and 1.
If you declare them as byte or unsigned int, they can take:
0,1,2 and 3

Here are some you could use for 3bit:
Code: [Select]
`struct Cell {      byte a : 3;      byte b : 3;      byte : 2; //empty as 3bit doesn't fit neatly.   }; //Total size = 1byte struct Cell {      byte a : 3;      byte b : 3;      byte c : 3;      byte d : 3;      byte e : 3;      byte : 1; //empty as 3bit doesn't fit neatly.   }; //Total size = 2bytes struct Cell {      byte a : 3;      byte b : 3;      byte c : 3;      byte d : 3;      byte e : 3;      byte f : 3;      byte g : 3;      byte h : 3;   }; //Total size = 3bytes`
~Tom~

#### flocked

#4
##### Oct 03, 2013, 11:54 pmLast Edit: Oct 04, 2013, 01:46 am by flocked Reason: 1
Okay, thanks.

So If I would want to have 3 bit numbers I say:
Code: [Select]
`   struct Cell {      byte a : 3;      byte b : 3;   };`

Two bytes would stay unused…Seems to be space waste. Any better way? :/

#### KeithRB

#5
##### Oct 04, 2013, 12:16 am
Just use the high and low nibble of a byte to store your numbers. You will need to write separate code to unpack and use them.
I think it would be much better to just save them as individual bytes. Do you really have that many of them?

#### guix

#6
##### Oct 04, 2013, 01:14 amLast Edit: Oct 04, 2013, 01:15 am by guix Reason: 1

So If I would want to have 3 bit numbers I say:
Code: [Select]
`   struct Cell {      byte a : 3;      byte b : 3;   };`

Two bytes would stay unused…Seems to be space space. Any better way? :/

No you just waste 2 bits, but as the byte is the smallest addressable unit of memory, you lose no memory

#### PeterH

#7
##### Oct 04, 2013, 02:09 am

Is it possible to save 2 & 3 bit values? I don't want to use integers, because they are to big…

Save where? And how many are you planning to save?
I only provide help via the forum - please do not contact me for private consultancy.

#### SirNickity

#8
##### Oct 04, 2013, 05:23 am

So If I would want to have 3 bit numbers I say:
Code: [Select]
`   struct Cell {      byte a : 3;      byte b : 3;   };`

Two bytes would stay unused…Seems to be space space. Any better way? :/

Bit fields get a bad rap sometimes because they're "implementation dependent" -- meaning the compiler can store that data any way it chooses to, including allocating dedicated integers for every field.  In practice, most compilers do something sensible.

A caveat worth noting is the layout in memory is not defined, so you have to use the struct to access the values -- i.e., you can't just use e.g., memcpy and expect the data to be meaningful to another computer...  Particularly important for applications that share data via files on disk or over the network.  In short:  The resulting memory layout is not portable, but as long as you only touch the contents via the struct interface, you're fine.

In your given case, what happens is the compiler will (probably) allocate one byte of memory, and store the two struct elements (A and B) as 3-bit fields within that one byte.  This is the most (memory-) efficient way it can be done, as it is essentially the same thing as using shift operators yourself on a single byte variable, but more human-readable.  Either way, 2 bits are wasted (you're only using six of the eight available).  Nothing can be done about that.

Of course, if you're intending to store a finite but significant amount of 3-bit fields, you can make that struct rather large ... with elements from A to Z, for example ... and the compile will (presumably) pack the fields together into however many bytes are physically necessary to hold them all.  Although, some compilers may not allow individual fields to span across whatever native allocation boundary it uses -- possibly 8-bits, or 16, or 32, 64...  So you may end up wasting 2 bits for every 6, or 1 bit every 15, etc...

#### Nick Gammon

#9
##### Oct 04, 2013, 06:35 am

Is it possible to save 2 & 3 bit values? I don't want to use integers, because they are to big…

Use a char or byte then.

How many of these are you planning to have? Sounds like a lot of work unless you have hundreds of them.
Please post technical questions on the forum, not by personal message. Thanks!

http://www.gammon.com.au/electronics

#### robtillaart

#10
##### Oct 04, 2013, 02:54 pm

can you make arrays of those bitfields?  // popped up suddenly

something like

Struct cell
{
int b[4] : 8
}

(OK I can test sketch this
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

#### wildbill

#11
##### Oct 04, 2013, 03:08 pm
If you really want to store data in 3 bit chunks, you can do it in a RAM efficient way by bit twiddling operations - declare an array of unsigned char that has enough bits in it to store what you need. Then it's a (fairly) easy matter of coding  read and write accessor functions to get/set the nth set of 3 bits.

The question remains though - why do you need to do this?

#### robtillaart

#12
##### Oct 04, 2013, 03:30 pm
because it can be done?
exploring the limits of what is possible is one of humans biggest driving forces.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

#### wildbill

#13
##### Oct 04, 2013, 03:58 pm
I was trying to find Raymond Chen's remark about what kind of nails do you use for Balsa wood, but this was as close as I got:

http://blogs.msdn.com/b/oldnewthing/archive/2006/03/23/558887.aspx

Starts off with:
Quote
A common obstacle when trying to help people solve their problems is that what people ask for and what they actually want are not always the same thing.

Not always true of course, but it's certainly seen here often enough - hence the query

#### PeterH

#14
##### Oct 04, 2013, 03:58 pm

because it can be done?
exploring the limits of what is possible is one of humans biggest driving forces.

True, but the appropriate way to save data depends entirely on what data is being stored and what constraints need to be met - if this is only an academic exercise then the data can be stored however you want, but if this is an attempt to solve a real problem then we need much more information about the problem before we can advise how best to solve it.
I only provide help via the forum - please do not contact me for private consultancy.

Go Up

Please enter a valid email to subscribe