Reciprocal of 3 bits in C?

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
For some reason I just can't figure out how to do this. Reciprocal of 3 bits in C? For example

0b001 becomes 0b100
ob011 becomes 0b110
0c100 becomes 0b001


and so on.
 

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
Repeat three times:
Rotate source right - rotate carry left into reciprocal byte

Which processor?
C or assembler?

C

It is a Pic, not sure why that would matter.

And sorry I don't understand the suggestion. I mean I do basically but don't know how to implement.
 

AlbertHall

Joined Jun 4, 2014
12,636
PIC assembler:
This code will destroy the source data. Store it somewhere if you will need it again.
Code:
rrf source
rlf dest
rrf source
rlf dest
rrf source
rlf dest
 

Norfindel

Joined Mar 6, 2008
326
My C is a little bit rusty, but you could do that with:

C:
destination = 0;
if (source & 1) destination = destination | 4;
if (source & 2) destination = destination | 2;
if (source & 4) destination = destination | 1;
 
Last edited:

WBahn

Joined Mar 31, 2012
32,942
For some reason I just can't figure out how to do this. Reciprocal of 3 bits in C? For example

0b001 becomes 0b100
ob011 becomes 0b110
0c100 becomes 0b001


and so on.
By reciprocal, do you mean the reverse bit order?

In general, if you don't mind destroying the original data, you can do the following (provided the data types are compatible unsigned integers).

C:
for (int bit = 0; bit < BITS; bit++)
{
   dest = (dest << 1) | (source % 0x01);
   source >>= 1;
}
If BITS is defined to be the full width of dest, then there is no need to initialize it since the current contents will get push out the msb. But if BITS is less than that width, it is probably best to initialize it to 0 before the loop, unless you need to retain that information or you know you will never look at those bits.

If you only have three bits, it's likely quicker to just hardcode it as shown by Norfindel.
 

ebp

Joined Feb 8, 2018
2,332
Albert's method is pretty much exactly what I used when I designed in a real time clock calendar chip that had the stupid bits in the wrong stupid order. Stupid, stupid thing! I putzed about with standard C, which looked fairly elegant, and got absolutely abominable code generated - big and slow. I didn't need to conserve program space or have fast execution, but the mess just offended my sensibilities. I used assembler with shift through the carry bit, which was compact, neat and fast. I had to do 8 bits, so I put the assembler inside a simple C loop, but for only 3 bits doing it entirely in-line is just as/more efficient.
 

MrChips

Joined Oct 2, 2009
34,903
A simple solution is a lookup table.

unsigned char bit_reverse[8] = {0, 4, 2, 6, 1 , 5, 3, 7};

bits = bit_reverse[x];
 

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
A simple solution is a lookup table.

unsigned char bit_reverse[8] = {0, 4, 2, 6, 1 , 5, 3, 7};

bits = bit_reverse[x];

Already done last night but thanks! ;)

I was going to just set the bits but realized I would need a big switch statement anyway. What I need to be able to do is to constantly loop through the numbers from 0-7 to set a latch. Lot easier to do it with a loop and something like the lookup to set the latch.
 
Top