Can someone please explain the left/right shift behaviour in Golang. Please refer the sample code here: https://play.golang.org/p/7vjwCbOEkw
package main
import (
"fmt"
)
func main() {
var lf int8 = -3
fmt.Printf("-3 : %08b\n", lf)
fmt.Printf("<<1: %08b\n", lf<<1)
fmt.Printf("<<2: %08b\n", lf<<2)
fmt.Printf("<<3: %08b\n", lf<<3)
fmt.Printf("<<4: %08b\n", lf<<4)
fmt.Printf("<<5: %08b, %d\n", lf<<5, lf<<5)
fmt.Printf("<<6: %08b, %d\n", lf<<6, lf<<6)
fmt.Printf("<<7: %08b, %d\n", lf<<7, lf<<7)
fmt.Printf("<<8: %08b, %d\n", lf<<8, lf<<8)
fmt.Printf("<<9: %08b, %d\n", lf<<9, lf<<9)
}
-3 : -0000011
<<1: -0000110
<<2: -0001100
<<3: -0011000
<<4: -0110000
<<5: -1100000, -96
<<6: 01000000, 64
<<7: -10000000, -128
<<8: 00000000, 0
<<9: 00000000, 0
-3 is, in two's complement, 11111101 and what you see when the program prints -0000011 is a - and the binary representation of the absolute value of the number. In two's complement, the highest bit is 0 for positive (including zero), and 1 for negative numbers. If you shift this number (11111101) left, the lower 7 bits move one to the left and a 0 comes in from the right, replacing the lowest bit. Shifting as you do in your example will result in:
11111101 -3
11111010 -6
11110100 -12
11101000 -24
11010000 -48
10100000 -96
01000000 64
10000000 -128
00000000 0
00000000 0
...
You just have to consider all the bit patterns as two's complement, once you know how that works, everything will make sense.
Related
How do you apply a mask to get only one bit after you shift right? Does it depend on how many positions you shifted right?
In a 32 bit structure I'm trying to get the value of the 9th bit and the 10th bit.
x := uint32(11537664)
0000 0000 1011 0000 0000 1101 0000 0000
^^
So for the 9th bit, if I shift right 23 bits I need to mask one byte? That seems to isolate the 9th bit because I'm getting a value of 1.
(x >> 23) & 0xff
9th bit...should be 1... looks ok.
00000000000000000000000000000001
0x1
So to get the 10th bit which should be 0 I am shifting one less bit which does make 0 all the way to the right. But there is a 1 after it which needs to be masked. I figured 1 byte plus 1 bit for the mask but I'm still seeing the the bit in position two so that can't be right.
(x >> 22) & 0x1ff
10th bit... should be 0, but this shift and mask does not look correct.
00000000000000000000000000000010
^ This bit I don't want.
0x2
Link to example:
https://play.golang.org/p/zqofCAAKDZz
package main
import (
"fmt"
)
func bin(i uint32) {
fmt.Printf("%032b\n", i)
}
func hex(i uint32) {
fmt.Printf("0x%x\n", i)
}
func show(i uint32) {
bin(i)
hex(i)
fmt.Println()
}
func main() {
x := uint32(11537664)
fmt.Println("Data")
show(x)
fmt.Println("First 8 bits.")
show(x >> 24)
fmt.Println("9th bit...should be 1")
show((x >> 23) & 0xff)
fmt.Println("10th bit... should be 0")
show((x >> 22) & 0x1ff)
}
After the shift you get a number being 0b10, and you only need the lowest bit. So why are you masking with 0x1ff? That has 9 one bits, that will leave the lowest 9 bits unchanged (unmasked).
Instead mask with 0b01 = 0x01. That only leaves the lowest bit, and zeroes all others:
show((x >> 22) & 0x01)
Try it on the Go Playground.
Also note that if you just want to test if a certain bit is one or zero, you don't neccessarily have to shift. Masking by a proper bitmask that contains a single one at the certain position is enough. You may compare the masking result with zero.
The proper bitmask for testing the nth bit is simply 1<<n (where bits are zero indexed). The 2 bits you want to test are the 22. and 23. bits.
See this example:
x := uint32(11537664)
fmt.Printf("x : %032b\n", x)
fmt.Println()
const mask22 = 1 << 22
fmt.Printf("mask22 : %032b\n", mask22)
fmt.Printf("22. bit: %032b %t\n", x&mask22, x&mask22 != 0)
fmt.Println()
const mask23 = 1 << 23
fmt.Printf("mask23 : %032b\n", mask23)
fmt.Printf("23. bit: %032b %t\n", x&mask23, x&mask23 != 0)
It outputs (try it on the Go Playground):
x : 00000000101100000000110100000000
mask22 : 00000000010000000000000000000000
22. bit: 00000000000000000000000000000000 false
mask23 : 00000000100000000000000000000000
23. bit: 00000000100000000000000000000000 true
In the Go Tour exercise #17, I don't understand this expression 1 << uint(i)
package main
import "fmt"
func main() {
pow := make([]int, 10)
for i := range pow {
pow[i] = 1 << uint(i)
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
}
What is the purpose of this operator ? <<
The program outputs:
1
2
4
8
16
32
64
128
256
512
Program exited.
Its a binary shift operator. Specifically, its a left shift (since they point to the left).
What it does, is move all bits in the binary representation of a number ... left.
For example. The binary representation of 1 is (with a safe assumption of 8 bits per byte): 00000001. Applying a left shift produces:
00000001
<<
00000010
Which is the binary representation of 2. Applying it again produces:
00000010
<<
00000100
..which is the binary representation of 4.. and so on.
Conversely, a right shift >> does the opposite, so applying >> to the value 4, produces:
00000100
>>
00000010
..2.
You can change the tour to count backwards by using the right shift operator:
pow[i] = 512 >> uint(i)
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
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.
I'm trying to solve a riddle in a programming test.
Disclaimer: It's a test for a job, but I'm not looking for an answer. I'm just looking for an understanding of how to do this. The test requires that I come up with a set of solutions to a set of problems within 2 weeks, and it doesn't state a requirement that I arrive at the solutions in isolation.
So, the problem:
I have a 32-bit number with the bits arranged like this:
siiiiiii iiiiiiii ifffffff ffffffff
Where:
s is the sign bit (1 == negative)
i is 16 integer bits
f is 15 fraction bits
The assignment is to write something that decodes a 32-bit integer into a floating-point number. Given the following inputs, it should produce the following outputs:
input output
0x00008000 1.0
0x80008000 -1.0
0x00010000 2.0
0x80014000 -2.5
0x000191eb 3.14
0x00327eb8 100.99
I'm having no trouble getting the sign bit or the integer part of the number. I get the sign bit like this:
boolean signed = ((value & (1 << 31)) != 0);
I get the integer and fraction parts like this:
int wholePart = ((value & 0x0FFFFFFF) >> 15);
int fractionPart = ((value & 0x0000FFFF >> 1));
The part I'm having an issue with is getting the number in the last 15 bits to match the expected values.
Instead of 3.14, I get 3.4587, etc.
If someone could give me a hint about what I'm doing wrong, I'd appreciate it. More than anything else, the fact that I haven't figured this out after hours of messing with it is kind of driving me nuts. :-)
Company's inputs aren't wrong. The fractional bits don't represent the the literal digits right of the decimal point, they represent the fractional part. Don't know how else to say it without giving it away. Would it be too big a hint to say there is a divide involved?
A few things...
Why not get the fractional part as
int fractionPart = value & 0x00007FFF; // i.e. no shifting needed...
Similarly, no shifting needed for the sign
boolean signed = ((value & (0x80000000) != 0); // signed is true when negative
See Ryan's response for the effective use of the fractional part, i.e. not taking this literally as the digit values for the decimal part but rather... some' involving a fraction...
Have a look at what you're anding the fraction part with prior to the shift.
Shift Right 31 gives you the signed bit 1=Neg 0=Pos
BEFORE siiiiiii iiiiiiii ifffffff ffffffff
SHR 31 00000000 00000000 00000000 0000000s
Shift Left 1 followed by Shift Right 16 gives you the Integer bits
BEFORE siiiiiii iiiiiiii ifffffff ffffffff
SHL 1 iiiiiiii iiiiiiii ffffffff fffffff0
SHR 16 00000000 00000000 iiiiiiii iiiiiiii
Shift Left 17 followed by Shift Right 15 gives for the Faction bits
BEFORE siiiiiii iiiiiiii ifffffff ffffffff
SHL 17 ffffffff fffffff0 00000000 00000000
SHR 16 00000000 00000000 0fffffff ffffffff
int wholePart = ((value & 0x7FFFFFFF) >> 15);
int fractionPart = (value & 0x00007FFF);
Key your bit-mask into Calculator in Binary mode and then flip it to Hex...