Breaking a 32 bit integer into 8 bit chucks for Radix Sort - radix-sort

I am basically a beginner in Computer Science. Please forgive me if I ask elementary questions. I am trying to understand radix sort. I read that a 32 bit unsigned integer can be broken down into 4 8-bit chunks. After that, all it takes is "4 passes" to complete the radix sort. Can somebody please show me an example for how this breakdown (32 bit into 4 8-bit chunks) works? Maybe, a 32-bit integer like 2147507648.
Thanks!

You would divide the 32 bit integer up in 4 pieces of 8 bits. Extracting those pieces is a matter of using using some of the operators available in C.:
uint32_t x = 2147507648;
uint8_t chunk1 = x & 0x000000ff; //lower 8 bits
uint8_t chunk2 = (x & 0x0000ff00) >> 8;
uint8_t chunk3 = (x & 0x00ff0000) >> 16;
uint8_t chunk4 = (x & 0xff000000) >> 24; //highest 8 bits
2147507648 decimal is 0x80005DC0 hex. You an pretty much eyeball those 8 bits out of the hex representation, since each hex digit represents 4 bits, two and two of them represents 8 bits.
So that now means chunk 1 is 0xC0, chunk 2 is 0x5D, chunk3 is 0x00 and chunk 4 is 0x80

It's done as follows:
2147507648
=> 0x80005DC0 (hex value of 2147507648)
=> 0x80 0x00 0x5D 0xC0
=> 128 0 93 192
To do this, you'd need bitwise operations as nos suggested.

Related

Encode/decoded a randomized, fixed-length string to and from a 64 bit integer

I want to convert a fixed-length, say 50 character long randomized string into a 64 bit integer and be able to convert it back to original text given the 64 bit integer.
Does an algorithm exist for this? I want to go with encoding/decoding rather than hashing/reverse lookup.
just sumarization of the comments...
1:1 mapping between string and number requires enough characters and bits to store your data. Assuming 26 char alphabet only:
64bit -> 2^64 // possible numbers in 64 bits
1char -> 26 // possible characters per 1 char
so in order to get the number of chars fitting into 64 bit integer
chars = floor( 64 / (log(26)/log(2)) )
= floor( 64 / 4.7004397181410921603968126542567)
= floor( 13.6 )
= 13
if you want to know how many bits you need for 50 chars:
bits = ceil( 50 / (log(2)/log(26)) )
= ceil( 50 / 0.21274605355336315360618778415321
= ceil( 235.02198590705460801984063271284 )
= 236
Now if you want to encode 13 char (a..z) from text into 64 bit unsigned integer x:
char text[13] = "bla bla bla b";
unsigned int x,m,i;
for (i=0,x=0,m=1;i<13;i++,m*=26)
x += ((unsigned int)(text[i]-'a'))*m;
And decoding back:
for (i=0;i<13;i++)
{
text[i] = (x%26)+'a';
x /= 26;
}
As you can see its the same as converting between numbers in different bases...
In case you want to have faster dec/enc at the cost of text size you can ceil the number of bits per single character to 5 meaning floor(64/5) = 12 chars and use bits operations instead (each character would be 5 bits in the number)...
char text[12] = "bla bla bla ";
unsigned int x,i;
for (i=0,x=0,i<12;i++)
{
x <<= 5;
x |= text[i]-'a';
}
for (i=0;i<12;i++)
{
text[11-i] = (x&31)+'a';
x >>= 5;
}
However if you have any additional knowledge about the characters its possible to implement compression but only in cases where entropy allows it... for more info google RLE,Huffman encoding...

go - encoding unsigned 16 bit float in binary

In Go, how can I encode a float into a byte array as a 16 bit unsigned float with 11 explicit bits of mantissa and 5 bits of explicit exponent?
There doesn't seem to be a clean way to do it. The only thing I can think of is encoding it as in Convert byte array "[]uint8" to float64 in GoLang and manually truncating the bits.
Is there a "go" way to do this?
Here's the exact definition:
A 16 bit unsigned float with 11 explicit bits of mantissa and 5 bits of explicit exponent
The bit format is loosely modeled after IEEE 754. For example, 1 microsecond is represented as 0x1, which has an exponent of zero, presented in the 5 high order bits, and mantissa of 1, presented in the 11 low order bits. When the explicit exponent is greater than zero, an implicit high-order 12th bit of 1 is assumed in the mantissa. For example, a floatingvalue of 0x800 has an explicit exponent of 1, as well as an explicit mantissa of 0, but then has an effective mantissa of 4096 (12th bit is assumed to be 1). Additionally, the actual exponent is one-less than the explicit exponent, and the value represents 4096 microseconds. Any values larger than the representable range are clamped to 0xFFFF.
I am not sure whether I understand the encoding correctly (see my comment on the original question), but here is a function which may do what you want:
func EncodeFloat(seconds float64) uint16 {
us := math.Floor(1e6*seconds + 0.5)
if us < 0 {
panic("cannot encode negative value")
} else if us > (1<<30)*4095+0.5 {
return 0xffff
}
usInt := uint64(us)
expBits := uint16(0)
if usInt >= 2048 {
exp := uint16(1)
for usInt >= 4096 {
exp++
usInt >>= 1
}
usInt -= 2048
expBits = exp << 11
}
return expBits | uint16(usInt)
}
(code is at http://play.golang.org/p/G599VOBMcL )

how to compress the three bytes data into two bytes in java

I have to compress the 3 bytes of data in to two bytes.
the 3 bytes data includes day is in one byte,hour is in another byte, finally minutes is in one more byte.so totally i have 3 bytes data.how could i flip this data into two bytes only.
Thanks,
Minutes are ranging from 0 to 59 so the number could be stored on 6
bits (6 bits => 0 to 63)
Hours are ranging from 0 to 23 the number
could be stored on 5 bits (5 bits => 0 to 31)
Days... Err... Ranging from 0 to 6 ? Let's asusme that. 2 bytes = 16 bits, minus the 11
other bits, so you have 5 bits left which is more than enough.
To pack your 3 bytes of data into two, you have to dispatch the bits :
I will set bits 0 to 5 for the minutes, bits 6 to 10 for the hours, and the bits left for the day number.
So the formula to pack the bits is :
packed=minutes+hours*64+days*2048
To get back your uncompressed data :
minutes=packed & 63
hours=(packed & 1984) / 64
days=(packed & 63488) / 2048
I assume you need day from 1-31, hour from 0-23 and minute from 0-59, you thus need 5 bits for the day, 5 bits for the hours and 6 bits for the minutes. This makes exactly 16 bits. You should put 5 bits (day) and the first 3 bits for hours into your first byte and the remaining 2 bits for hours and the 6 bits for minutes into the second byte:
int day = 23;
int hour = 15;
int minute = 34;
byte fromint_dh = (day << 3) | (hour >> 2);
byte fromint_hm = ((hour & 0x03) << 6) | (minute); // take the last two bits from hour and put them at the beginning
....
int d = fromint_dh >> 3;
int h = ((fromint_dh & 0x07) << 2) | ((fromint_hm & 0xc0) >> 6); // take the last 3 bits of the fst byte and the fst 2 bits of the snd byte
int m = fromint_hm & 0x3F // only take the last 6 bits
Hope this helps. It's easy to get the bits wrong ...

How to calculate g values from LIS3DH sensor?

I am using LIS3DH sensor with ATmega128 to get the acceleration values to get motion. I went through the datasheet but it seemed inadequate so I decided to post it here. From other posts I am convinced that the sensor resolution is 12 bit instead of 16 bit. I need to know that when finding g value from the x-axis output register, do we calculate the two'2 complement of the register values only when the sign bit MSB of OUT_X_H (High bit register) is 1 or every time even when this bit is 0.
From my calculations I think that we calculate two's complement only when MSB of OUT_X_H register is 1.
But the datasheet says that we need to calculate two's complement of both OUT_X_L and OUT_X_H every time.
Could anyone enlighten me on this ?
Sample code
int main(void)
{
stdout = &uart_str;
UCSRB=0x18; // RXEN=1, TXEN=1
UCSRC=0x06; // no parit, 1-bit stop, 8-bit data
UBRRH=0;
UBRRL=71; // baud 9600
timer_init();
TWBR=216; // 400HZ
TWSR=0x03;
TWCR |= (1<<TWINT)|(1<<TWSTA)|(0<<TWSTO)|(1<<TWEN);//TWCR=0x04;
printf("\r\nLIS3D address: %x\r\n",twi_master_getchar(0x0F));
twi_master_putchar(0x23, 0b000100000);
printf("\r\nControl 4 register 0x23: %x", twi_master_getchar(0x23));
printf("\r\nStatus register %x", twi_master_getchar(0x27));
twi_master_putchar(0x20, 0x77);
DDRB=0xFF;
PORTB=0xFD;
SREG=0x80; //sei();
while(1)
{
process();
}
}
void process(void){
x_l = twi_master_getchar(0x28);
x_h = twi_master_getchar(0x29);
y_l = twi_master_getchar(0x2a);
y_h = twi_master_getchar(0x2b);
z_l = twi_master_getchar(0x2c);
z_h = twi_master_getchar(0x2d);
xvalue = (short int)(x_l+(x_h<<8));
yvalue = (short int)(y_l+(y_h<<8));
zvalue = (short int)(z_l+(z_h<<8));
printf("\r\nx_val: %ldg", x_val);
printf("\r\ny_val: %ldg", y_val);
printf("\r\nz_val: %ldg", z_val);
}
I wrote the CTRL_REG4 as 0x10(4g) but when I read them I got 0x20(8g). This seems bit bizarre.
Do not compute the 2s complement. That has the effect of making the result the negative of what it was.
Instead, the datasheet tells us the result is already a signed value. That is, 0 is not the lowest value; it is in the middle of the scale. (0xffff is just a little less than zero, not the highest value.)
Also, the result is always 16-bit, but the result is not meant to be taken to be that accurate. You can set a control register value to to generate more accurate values at the expense of current consumption, but it is still not guaranteed to be accurate to the last bit.
the datasheet does not say (at least the register description in chapter 8.2) you have to calculate the 2' complement but stated that the contents of the 2 registers is in 2's complement.
so all you have to do is receive the two bytes and cast it to an int16_t to get the signed raw value.
uint8_t xl = 0x00;
uint8_t xh = 0xFC;
int16_t x = (int16_t)((((uint16)xh) << 8) | xl);
or
uint8_t xa[2] {0x00, 0xFC}; // little endian: lower byte to lower address
int16_t x = *((int16*)xa);
(hope i did not mixed something up with this)
I have another approach, which may be easier to implement as the compiler will do all of the work for you. The compiler will probably do it most efficiently and with no bugs too.
Read the raw data into the raw field in:
typedef union
{
struct
{
// in low power - 8 significant bits, left justified
int16 reserved : 8;
int16 value : 8;
} lowPower;
struct
{
// in normal power - 10 significant bits, left justified
int16 reserved : 6;
int16 value : 10;
} normalPower;
struct
{
// in high resolution - 12 significant bits, left justified
int16 reserved : 4;
int16 value : 12;
} highPower;
// the raw data as read from registers H and L
uint16 raw;
} LIS3DH_RAW_CONVERTER_T;
than use the value needed according to the power mode you are using.
Note: In this example, bit fields structs are BIG ENDIANS.
Check if you need to reverse the order of 'value' and 'reserved'.
The LISxDH sensors are 2's complement, left-justified. They can be set to 12-bit, 10-bit, or 8-bit resolution. This is read from the sensor as two 8-bit values (LSB, MSB) that need to be assembled together.
If you set the resolution to 8-bit, just can just cast LSB to int8, which is the likely your processor's representation of 2's complement (8bit). Likewise, if it were possible to set the sensor to 16-bit resolution, you could just cast that to an int16.
However, if the value is 10-bit left justified, the sign bit is in the wrong place for an int16. Here is how you convert it to int16 (16-bit 2's complement).
1.Read LSB, MSB from the sensor:
[MMMM MMMM] [LL00 0000]
[1001 0101] [1100 0000] //example = [0x95] [0xC0] (note that the LSB comes before MSB on the sensor)
2.Assemble the bytes, keeping in mind the LSB is left-justified.
//---As an example....
uint8_t byteMSB = 0x95; //[1001 0101]
uint8_t byteLSB = 0xC0; //[1100 0000]
//---Cast to U16 to make room, then combine the bytes---
assembledValue = ( (uint16_t)(byteMSB) << UINT8_LEN ) | (uint16_t)byteLSB;
/*[MMMM MMMM LL00 0000]
[1001 0101 1100 0000] = 0x95C0 */
//---Shift to right justify---
assembledValue >>= (INT16_LEN-numBits);
/*[0000 00MM MMMM MMLL]
[0000 0010 0101 0111] = 0x0257 */
3.Convert from 10-bit 2's complement (now right-justified) to an int16 (which is just 16-bit 2's complement on most platforms).
Approach #1: If the sign bit (in our example, the tenth bit) = 0, then just cast it to int16 (since positive numbers are represented the same in 10-bit 2's complement and 16-bit 2's complement).
If the sign bit = 1, then invert the bits (keeping just the 10bits), add 1 to the result, then multiply by -1 (as per the definition of 2's complement).
convertedValueI16 = ~assembledValue; //invert bits
convertedValueI16 &= ( 0xFFFF>>(16-numBits) ); //but keep just the 10-bits
convertedValueI16 += 1; //add 1
convertedValueI16 *=-1; //multiply by -1
/*Note that the last two lines could be replaced by convertedValueI16 = ~convertedValueI16;*/
//result = -425 = 0xFE57 = [1111 1110 0101 0111]
Approach#2: Zero the sign bit (10th bit) and subtract out half the range 1<<9
//----Zero the sign bit (tenth bit)----
convertedValueI16 = (int16_t)( assembledValue^( 0x0001<<(numBits-1) ) );
/*Result = 87 = 0x57 [0000 0000 0101 0111]*/
//----Subtract out half the range----
convertedValueI16 -= ( (int16_t)(1)<<(numBits-1) );
[0000 0000 0101 0111]
-[0000 0010 0000 0000]
= [1111 1110 0101 0111];
/*Result = 87 - 512 = -425 = 0xFE57
Link to script to try out (not optimized): http://tpcg.io/NHmBRR

To convert RGB 12 bit data to RGB 12 bit packed data

I have some RGB(image) data which is 12 bit. Each R,G,B has 12 bits, total 36 bits.
Now I need to club this 12 bit RGB data into a packed data format. I have tried to mention the packing as below:-
At present I have input data as -
B0 - 12 bits G0 - 12 bits R0 - 12 bits B1 - 12 bits G1 - 12 bits R1 - 12 bits .. so on.
I need to convert it to packed format as:-
Byte1 - B8 (8 bits of B0 data)
Byte2 - G4B4 (remaining 4 bits of B0 data+ first 4 bits of G0)
Byte3 - G8 (remaining 8 bits of G0)
Byte4 - R8 (first 8 bits of R0)
Byte5 - B4R4 (first 4 bits of B1 + last 4 bits of R0)
I have to write these individual bytes to a file in text format. one byte below another.
Similar thing i have to do for a 10 bit RGB input data.
Is there any tool/software to get the conversion of data i am looking to get done.
I am trying to do it in a C program - I am forming a 64 bit from the individual 12 bits of R,G,B (total 36 bits). But after that I am not able to come up with a logic to pick
the necessary bits from a R,G,B data to form a byte stream, and to dump them to a text file.
Any pointers will be helpful.
This is pretty much untested, super messy code I whipped together to give you a start. It's probably not packing the bytes exactly as you want, but you should get the general idea.
Apologies for the quick and nasty code, only had a couple of minutes, hope it's of some help anyway.
#include <stdio.h>
typedef struct
{
unsigned short B;
unsigned short G;
unsigned short R;
} UnpackedRGB;
UnpackedRGB test[] =
{
{0x0FFF, 0x000, 0x0EEE},
{0x000, 0x0FEF, 0xDEF},
{0xFED, 0xDED, 0xFED},
{0x111, 0x222, 0x333},
{0xA10, 0xB10, 0xC10}
};
UnpackedRGB buffer = {0, 0, 0};
int main(int argc, char** argv)
{
int numSourcePixels = sizeof(test)/sizeof(UnpackedRGB);
/* round up to the last byte */
int destbytes = ((numSourcePixels * 45)+5)/10;
unsigned char* dest = (unsigned char*)malloc(destbytes);
unsigned char* currentDestByte = dest;
UnpackedRGB *pixel1;
UnpackedRGB *pixel2;
int ixSource;
for (ixSource = 0; ixSource < numSourcePixels; ixSource += 2)
{
pixel1 = &test[ixSource];
pixel2 = ((ixSource + 1) < numSourcePixels ? &test[ixSource] : &buffer);
*currentDestByte++ = (0x0FF) & pixel1->B;
*currentDestByte++ = ((0xF00 & pixel1->B) >> 8) | (0x0F & pixel1->G);
*currentDestByte++ = ((0xFF0 & pixel1->G) >> 4);
*currentDestByte++ = (0x0FF & pixel1->R);
*currentDestByte++ = ((0xF00 & pixel1->R) >> 8) | (0x0F & pixel2->B);
if ((ixSource + 1) >= numSourcePixels)
{
break;
}
*currentDestByte++ = ((0xFF0 & pixel2->B) >> 4);
*currentDestByte++ = (0x0FF & pixel2->G);
*currentDestByte++ = ((0xF00 & pixel2->G) >> 8) | (0x0F & pixel2->R);
*currentDestByte++ = (0xFF0 & pixel2->R);
}
FILE* outfile = fopen("output.bin", "w");
fwrite(dest, 1, destbytes,outfile);
fclose(outfile);
}
Use bitwise & (and), | (or), and shift <<, >> operators.

Resources