retrieve last 6 bits from an integer - c++

I need to fetch last 6 bits of a integer or Uint32. For example if I have a value of 183, I need last six bits which will be 110 111 ie 55.
I have written a small piece of code, but it's not behaving as expected. Could you guys please point out where I am making a mistake?
int compress8bitTolessBit( int value_to_compress, int no_of_bits_to_compress )
{
int ret = 0;
while(no_of_bits_to_compress--)
{
std::cout << " the value of bits "<< no_of_bits_to_compress << std::endl;
ret >>= 1;
ret |= ( value_to_compress%2 );
value_to_compress /= 2;
}
return ret;
}
int _tmain(int argc, _TCHAR* argv[])
{
int val = compress8bitTolessBit( 183, 5 );
std::cout <<" the value is "<< val << std::endl;
system("pause>nul");
return 0;
}

You have entered the realm of binary arithmetic. C++ has built-in operators for this kind of thing. The act of "getting certain bits" of an integer is done with an "AND" binary operator.
0101 0101
AND 0000 1111
---------
0000 0101
In C++ this is:
int n = 0x55 & 0xF;
// n = 0x5
So to get the right-most 6 bits,
int n = original_value & 0x3F;
And to get the right-most N bits,
int n = original_value & ((1 << N) - 1);
Here is more information on
Binary arithmetic operators in C++
Binary operators in general

I don't get the problem, can't you just use bitwise operators? Eg
u32 trimmed = value & 0x3F;
This will keep just the 6 least significant bits by using the bitwise AND operator.

tl;dr:
int val = x & 0x3F;

int value = input & ((1 << (no_of_bits_to_compress + 1) - 1)
This one calculates the (n+1)th power of two: 1 << (no_of_bits_to_compress + 1) and subtracts 1 to get a mask with all n bits set.

The last k bits of an integer A.
1. A % (1<<k); // simply A % 2^k
2. A - ((A>>k)<<k);
The first method uses the fact that the last k bits is what is trimmed after doing k right shits(divide by 2^k).

Related

Wrong result with bitwise inclusive OR

I can't figure out why does inclusive OR return wrong result.
char arr[] = { 0x0a, 0xc0 };
uint16_t n{};
n = arr[0]; // I get 0x000a here.
n = n << 8; // Shift to the left and get 0x0a00 here.
n = n | arr[1]; // But now the n value is 0xffc0 instead of 0x0ac0.
What is the mistake in this example? Console app, MVS Community 2017.
The unintended 0xff is caused by sign bit extension of 0xc0.
0xc0 = 0b11000000
Hence, the uppermost bit is set which means sign for char (as signed char).
Please, note that all arithmetic and bitwise operations in C++ work with at least int (or unsigned int). Smaller types are promoted before and clipped afterwards.
Please, note also that char may be signed or unsigned. That's compiler implementation dependent. Obviously, it's signed in the case of OP. To prevent the unintended sign extension, the argument has to become unsigned (early enough).
Demonstration:
#include <iostream>
int main()
{
char arr[] = { '\x0a', '\xc0' };
uint16_t n{};
n = arr[0]; // I get 0x000a here.
n = n << 8; // Shift to the left and get 0x0a00 here.
n = n | arr[1]; // But now the n value is 0xffc0 instead of 0x0ac0.
std::cout << std::hex << "n (wrong): " << n << std::endl;
n = arr[0]; // I get 0x000a here.
n = n << 8; // Shift to the left and get 0x0a00 here.
n = n | (unsigned char)arr[1]; // (unsigned char) prevents sign extension
std::cout << std::hex << "n (right): " << n << std::endl;
return 0;
}
Session:
g++ -std=c++11 -O2 -Wall -pthread main.cpp && ./a.out
n (wrong): ffc0
n (right): ac0
Life demo on coliru
Note:
I had to changechar arr[] = { 0x0a, 0xc0 };to char arr[] = { '\x0a', '\xc0' }; to come around serious compiler complaints. I guess, these complaints where strongly related to this issue.
I got it to work correctly by doing:
int arr[] = { 0x0a, 0xc0 };
int n{};
n = arr[0]; // I get 0x000a here.
n = n << 8; // Shift to the left and get 0x0a00 here.
n = n | arr[1];
std::cout << n << std::endl;
There was some truncation if you leave the 'arr' array as char.
You have fallen a victim to signed integer promotion.
When assigning 0xc0 to the second element (signed char default because of MVS) in the array, this is represented as follows:
arr[1] = 1100 - 0000, or in decimal -64
When this is cast to an uint16_t, it is promoted to an integer with the value -64. This is:
n = 1111 - 1111 - 1100 - 0000 = -64
due to the 2's complement implementation of integers.
Therefore:
n = 1111 - 1111 - 1100 - 0000
arr[1] = 0000 - 0000 - 1010 - 0000 (after being promoted)
n | arr[1] = 1111 - 1111 -1110-0000 = 0xffc0

How to split an unsigned long int (32 bit) into 8 nibbles?

I am sorry if my question is confusing but here is the example of what I want to do,
lets say I have an unsigned long int = 1265985549
in binary I can write this as 01001011011101010110100000001101
now I want to split this binary 32 bit number into 4 bits like this and work separately on those 4 bits
0100 1011 0111 0101 0110 1000 0000 1101
any help would be appreciated.
You can get a 4-bit nibble at position k using bit operations, like this:
uint32_t nibble(uint32_t val, int k) {
return (val >> (4*k)) & 0x0F;
}
Now you can get the individual nibbles in a loop, like this:
uint32_t val = 1265985549;
for (int k = 0; k != 8 ; k++) {
uint32_t n = nibble(val, k);
cout << n << endl;
}
Demo on ideone.
short nibble0 = (i >> 0) & 15;
short nibble1 = (i >> 4) & 15;
short nibble2 = (i >> 8) & 15;
short nibble3 = (i >> 12) & 15;
etc
Based on the comment explaining the actual use for this, here's an other way to count how many nibbles have an odd parity: (not tested)
; compute parities of nibbles
x ^= x >> 2;
x ^= x >> 1;
x &= 0x11111111;
; add the parities
x = (x + (x >> 4)) & 0x0F0F0F0F;
int count = x * 0x01010101 >> 24;
The first part is just a regular "xor all the bits" type of parity calculation (where "all bits" refers to all the bits in a nibble, not in the entire integer), the second part is based on this bitcount algorithm, skipping some steps that are unnecessary because certain bits are always zero and so don't have to be added.

Understanding this bitset implementation (C++)

I just got this frame for a sudoku solver, but I don't understand the syntax they've used and how I'm supposed to proceed. They call it a bitset, but upon searching for it I found nothing similar.
// This file contains a simple implementation of sets of
// digits between 1 and 9, called fields.
#ifndef __SUDOKU_FIELD_H__
#define __SUDOKU_FIELD_H__
#include <iostream>
#include <cassert>
#include "digit.h"
class Field {
private:
// Use integers for a bitset
unsigned int _digits;
// Number of digits in bitset
unsigned int _size;
public:
// Initialize with all digits between 1 and 9 included
Field(void)
: _digits((1 << 1) | (1 << 2) | (1 << 3) |
(1 << 4) | (1 << 5) | (1 << 6) |
(1 << 7) | (1 << 8) | (1 << 9)), _size(9) {}
// Return size of digit set (number of digits in set)
unsigned int size(void) const {
// FILL IN
}
// Test whether digit set is empty
bool empty(void) const {
// FILL IN
}
// Test whether set is assigned (that is, single digit left)
bool assigned(void) const {
// FILL IN
}
// Test whether digit d is included in set
bool in(digit d) const {
assert((d >= 1) && (d <= 9));
// FILL IN
}
// Return digit to which the set is assigned
digit value(void) const {
assert(assigned());
// FILL IN
}
// Print digits still included
void print(std::ostream& os) const;
// Remove digit d from set (d must be still included)
void prune(digit d) {
assert(in(d));
// FILL IN
}
// Assign field to digit d (d must be still included)
void assign(digit d) {
assert(in(d));
// FILL IN
}
};
// Print field
inline std::ostream&
operator<<(std::ostream& os, const Field& f) {
f.print(os); return os;
}
#endif
Obviously the //FILL IN's are for me to write, and the meaning of the bitset is 9 bits where all of them initially are set to 1. The question is how I manipulate or use them.
Oh, by the way, this is a digit:
#ifndef __SUDOKU_DIGIT_H__
#define __SUDOKU_DIGIT_H__
typedef unsigned char digit;
#endif
A "bitfield" is just an interpretation of a integer in memory as if it was a list of bits. You will be setting, testing and resetting bits in this integer individually, and the comments in the code tell you exactly what to do in each function.
You can use '&' and '|' for bitwise AND and OR, and '<<' and '>>' for shifting all bits to the left and right. This article can be very helpful to you: http://en.wikipedia.org/wiki/Bitwise_operation
This initialization sets the bits 1 - 9 of _digits to 1. The expression (1 << n) means 1 shifted n bits to the left. The expression a | b means a bit-wise or of a and b.
So, in detail, all of the expressions (1 << n) result in a bit-pattern with all zeroes and a 1 at the n th position, for 0 < n < 10. All of these are or'd together, to yield a bit-pattern bits 1 through 9 set to 1:
(1 << 1) 0010 |
(1 << 2) 0100 |
(1 << 3) 1000
======================
1110
(unused bits not shown)
4 bits:
0000
1 in binary is:
0001
Shifting is used to choose a single bit:
0001 << 0 = 0001 // first bit
0001 << 1 = 0010 // second bit
0001 << 2 = 0100 // third bit
Or is used to set individual bits:
0000 | 0100 = 0100
And is used to retrieve bits:
0111 & 0001 = 0001
This is how bitsets work.
Example:
unsigned int x = 0;
x |= 1 << 4; // set 5th bit
x |= 1 << 3; // set 4th bit
x |= 0x3; // set first 2 bits - 0x3 = 0011
unsigned int b = true;
x |= b << 7; // set 8th bit to value of b
if (x & (1 << 2)) { // check if 3rd bit is true
// ...
}
b = (x >> 3) & 1; // set b to value of 4th bit
Here is a way to count number of bits, along with other helpful algorithms:
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}

The tilde operator in C

I've seen the tilde operator used in the ELF hashing algorithm, and I'm curious what it does. (The code is from Eternally Confused.)
unsigned elf_hash ( void *key, int len )
{
unsigned char *p = key;
unsigned h = 0, g;
int i;
for ( i = 0; i < len; i++ ) {
h = ( h << 4 ) + p[i];
g = h & 0xf0000000L;
if ( g != 0 )
h ^= g >> 24;
h &= ~g;
}
return h;
}
The ~ operator is bitwise NOT, it inverts the bits in a binary number:
NOT 011100
= 100011
~ is the bitwise NOT operator. It inverts the bits of the operand.
For example, if you have:
char b = 0xF0; /* Bits are 11110000 */
char c = ~b; /* Bits are 00001111 */
This is the bitwise NOT operator.
It flips all the bits in a number: 100110 -> 011001
The tilde character is used as an operator to invert all bits of an integer (bitwise NOT).
For example: ~0x0044 = 0xFFBB.
It is the bitwise NOT operator. It inverts all bits in an integer value.
Tilde operator (~) also called bitwise NOT operator, performs one's complement of any binary number as argument. If the operand to NOT is decimal number then it convert it as binary and perform's one's complement operation.
To calculate one's complement simply invert all the digit [0-->1] and [1-->0]
Ex : 0101 = 5; ~(0101) = 1010.
Use of tilde operator :
1. It is used in masking operation , Masking means setting and resetting the values inside any register . for ex :
char mask ;
mask = 1 << 5 ;
It will set mask to a binary value of 10000 and this mask can be used to check the bit value present inside other variable .
int a = 4;
int k = a&mask ; if the 5th bit is 1 , then k=1 otherwise k=0.
This is called Masking of bits.
2.To find binary equivalent of any number using masking properties.
#include<stdio.h>
void equi_bits(unsigned char);
int main()
{
unsigned char num = 10 ;
printf("\nDecimal %d is same as binary ", num);
equi_bits(num);
return 0;
}
void equi_bits(unsigned char n)
{
int i ;
unsigned char j , k ,mask ;
for( i = 7 ; i >= 0 ; i--)
{
j=i;
mask = 1 << j;
k = n&mask ; // Masking
k==0?printf("0"):printf("1");
}
}
Output : Decimal 10 is same as 00001010
My observation :For the maximum range of any data type , one's complement provide the negative value decreased by 1 to any corresponding value.
ex: ~1 --------> -2
~2---------> -3
and so on... I will show you this observation using little code snippet
#include<stdio.h>
int main()
{
int a , b;
a=10;
b=~a; // b-----> -11
printf("%d\n",a+~b+1);// equivalent to a-b
return 0;
}
Output: 0
Note : This is valid only for the range of data type. means for int data type this rule will be applicable only for the value of range[-2,147,483,648 to 2,147,483,647].
Thankyou .....May this help you

Check value of least significant bit (LSB) and most significant bit (MSB) in C/C++

I need to check the value of the least significant bit (LSB) and most significant bit (MSB) of an integer in C/C++. How would I do this?
//int value;
int LSB = value & 1;
Alternatively (which is not theoretically portable, but practically it is - see Steve's comment)
//int value;
int LSB = value % 2;
Details:
The second formula is simpler. The % operator is the remainder operator. A number's LSB is 1 iff it is an odd number and 0 otherwise. So we check the remainder of dividing with 2. The logic of the first formula is this: number 1 in binary is this:
0000...0001
If you binary-AND this with an arbitrary number, all the bits of the result will be 0 except the last one because 0 AND anything else is 0. The last bit of the result will be 1 iff the last bit of your number was 1 because 1 & 1 == 1 and 1 & 0 == 0
This is a good tutorial for bitwise operations.
HTH.
You can do something like this:
#include <iostream>
int main(int argc, char **argv)
{
int a = 3;
std::cout << (a & 1) << std::endl;
return 0;
}
This way you AND your variable with the LSB, because
3: 011
1: 001
in 3-bit representation. So being AND:
AND
-----
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1
You will be able to know if LSB is 1 or not.
edit: find MSB.
First of all read Endianess article to agree on what MSB means. In the following lines we suppose to handle with big-endian notation.
To find the MSB, in the following snippet we will focus applying a right shift until the MSB will be ANDed with 1.
Consider the following code:
#include <iostream>
#include <limits.h>
int main(int argc, char **argv)
{
unsigned int a = 128; // we want to find MSB of this 32-bit unsigned int
int MSB = 0; // this variable will represent the MSB we're looking for
// sizeof(unsigned int) = 4 (in Bytes)
// 1 Byte = 8 bits
// So 4 Bytes are 4 * 8 = 32 bits
// We have to perform a right shift 32 times to have the
// MSB in the LSB position.
for (int i = sizeof(unsigned int) * 8; i > 0; i--) {
MSB = (a & 1); // in the last iteration this contains the MSB value
a >>= 1; // perform the 1-bit right shift
}
// this prints out '0', because the 32-bit representation of
// unsigned int 128 is:
// 00000000000000000000000010000000
std::cout << "MSB: " << MSB << std::endl;
return 0;
}
If you print MSB outside of the cycle you will get 0.
If you change the value of a:
unsigned int a = UINT_MAX; // found in <limits.h>
MSB will be 1, because its 32-bit representation is:
UINT_MAX: 11111111111111111111111111111111
However, if you do the same thing with a signed integer things will be different.
#include <iostream>
#include <limits.h>
int main(int argc, char **argv)
{
int a = -128; // we want to find MSB of this 32-bit unsigned int
int MSB = 0; // this variable will represent the MSB we're looking for
// sizeof(int) = 4 (in Bytes)
// 1 Byte = 8 bits
// So 4 Bytes are 4 * 8 = 32 bits
// We have to perform a right shift 32 times to have the
// MSB in the LSB position.
for (int i = sizeof(int) * 8; i > 0; i--) {
MSB = (a & 1); // in the last iteration this contains the MSB value
a >>= 1; // perform the 1-bit right shift
}
// this prints out '1', because the 32-bit representation of
// int -128 is:
// 10000000000000000000000010000000
std::cout << "MSB: " << MSB << std::endl;
return 0;
}
As I said in the comment below, the MSB of a positive integer is always 0, while the MSB of a negative integer is always 1.
You can check INT_MAX 32-bit representation:
INT_MAX: 01111111111111111111111111111111
Now. Why the cycle uses sizeof()?
If you simply do the cycle as I wrote in the comment: (sorry for the = missing in comment)
for (; a != 0; a >>= 1)
MSB = a & 1;
you will get 1 always, because C++ won't consider the 'zero-pad bits' (because you specified a != 0 as exit statement) higher than the highest 1. For example for 32-bit integers we have:
int 7 : 00000000000000000000000000000111
^ this will be your fake MSB
without considering the full size
of the variable.
int 16: 00000000000000000000000000010000
^ fake MSB
int LSB = value & 1;
int MSB = value >> (sizeof(value)*8 - 1) & 1;
Others have already mentioned:
int LSB = value & 1;
for getting the least significant bit. But there is a cheatier way to get the MSB than has been mentioned. If the value is a signed type already, just do:
int MSB = value < 0;
If it's an unsigned quantity, cast it to the signed type of the same size, e.g. if value was declared as unsigned, do:
int MSB = (int)value < 0;
Yes, officially, not portable, undefined behavior, whatever. But on every two's complement system and every compiler for them that I'm aware of, it happens to work; after all, the high bit is the sign bit, so if the signed form is negative, then the MSB is 1, if it's non-negative, the MSB is 0. So conveniently, a signed test for negative numbers is equivalent to retrieving the MSB.
LSB is easy. Just x & 1.
MSSB is a bit trickier, as bytes may not be 8 bits and sizeof(int) may not be 4, and there might be padding bits to the right.
Also, with a signed integer, do you mean the sign bit of the MS value bit.
If you mean the sign bit, life is easy. It's just x < 0
If you mean the most significant value bit, to be completely portable.
int answer = 0;
int rack = 1;
int mask = 1;
while(rack < INT_MAX)
{
rack << = 1;
mask << = 1;
rack |= 1;
}
return x & mask;
That's a long-winded way of doing it. In reality
x & (1 << (sizeof(int) * CHAR_BIT) - 2);
will be quite portable enough and your ints won't have padding bits.