I was wondering how to get C to not extend my binary number when I bitshift to the left
int main ()
{
unsigned int binary_temp = 0b0100;
binary_temp = binary_temp << 2;
printf("%d", binary_temp);
return 0;
}
When I run that I want a return value of 0 since it has extended past the 4 digits I have, but right now it returns 16 (10000). How would I get C not to extend my number?
Edit: I would like to be able to work with the number in binary form so I need to have only 4 digits, and not just outputting the right number.
It does not extend your number but saves it as unsigned int type which is 4 bytes (32 bits) in size. You only fill the last 4 bits. To treat it as only 4 bits, use Bitwise AND with a Mask value. Here's example code:
int main()
{
unsigned int binary_temp = 0b0100;
binary_temp = (binary_temp << 2) & 0b1111;
printf("%u", binary_temp);
return 0;
}
You can bitwise AND the result with a 4 bit mask value:
binary_temp = (binary_temp << 2) & 0xF;
There is no 0b in standard C. You could use 4.
unsigned int /* prepare for wtf identifier: */
binary_temp = 4;
Left shifting by 2 is multiplying by 4. Why not?
binary_temp *= 4;
... and then reduce modulo 16?
binary_temp %= 16;
What sense is there to using binary operators, in this case? I see none.
The %d directive corresponds to an int argument, but the argument you're giving printf is an unsigned int. That's undefined behaviour.
printf("%u", binary_temp);
I'm sure whichever book you're reading will tell you about the %u directive.
Related
Purpose: Demonstrate the ability to manipulate bits using functions and to learn a little bit about parity bits.
Parity is a type of error detection where one of the bits in a bit string is used for this purpose. There are more complicated systems that can do more robust error detection as well as error correction. In this lab, we will use a simple version called odd parity. This reserves one bit as a parity bit. The other bits are examined, and the parity bit is set so that the number of 1 bits is odd. For example, if you have a 3-bit sequence, 110 and the rightmost bit is the parity bit, it would be set to 1 to make the number of 1s odd.
Notes: When referring to bit positions, bit 31 is the high-order bit (leftmost), and bit 0 is the low-order bit (rightmost). In order to work through these functions, you will likely have to map out bit patterns for testing to see how it all works. You may find using a converter that can convert between binary, hex, and decimal useful. Also, to assign bit patterns to integers, it might be easier to use hex notation. To assign a hex value in C, you can use the 0x????? where ????? are hex values. (There can be more or fewer than the number of ? here.) E.g.,
int i = 0x02A;
Would assign i = 42 in decimal.
Program Specifications: Write the functions below:
unsigned int leftRotate(unsigned int intArg, unsigned int rotAmt);
Returns an unsigned int that is intArg rotated left by rotAmt. Note: Rotate left is similar to shift left. The difference is that the bits shifted out at the left come back in on the right. Rotate is a common operation and often is a single machine instruction. Do not convert intArg to a string and operate on that. Do not use an array of ints (or other numbers). Use only integers or unsigned integers.
Example: Assuming you have 5-bit numbers, rotating the binary number 11000 left by 3 yields 00110
char *bitString(int intArg)
Returns a pointer to a character string containing the 32-bit pattern for the integer argument. The first character, index 0, should be the high-order bit and on down from there. For this function, you will need malloc. Can be used for printing bit patterns. E.g., if intArg = 24 the return string would be 00000000000000000000000000011000
unsigned int oddParitySet3(unsigned int intArg, unsigned int startBit);
This function will determine the odd parity for a 3-bit segment of intArg starting at bit startBit and set the parity bit (low-order bit) appropriately.
E.g., suppose intArg=3 and startBit = 2. The 32 bit representation, from high to low, would be 29 zeros then 110. So, bits 2 - 0 are 011. To make the parity odd, you would set bit zero to 0.
The return value is the modified intArg, in this case it would be 29 zeros then 010 or a value of 2.
Do not convert intArg to a string and operate on that. Use only integers or unsigned integers.
Note: If the start bit is greater than 31 or less than 2, this would present a problem (do you see this?). If this is the case, return a zero.
The compile command used by this zyLab is:
gcc main.c -Wall -Werror -Wextra -Wuninitialized -pedantic-errors -o a.out -lm
The program does not pass all tests and gives such errors:
enter image description here
C code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char * bitString(int intArg);
unsigned int leftRotate(unsigned int n, unsigned int d);
unsigned int oddParitySet3(unsigned int intArg, unsigned int startBit);
int main() {
return 0;
}
char * bitString(int intArg)
{
char *bits = (char*)malloc(33 * sizeof(char));
bits[32] = '\0';
for(int i = 31; i >= 0; i--)
{
if(intArg & (1 << i))
bits[31 - i] = '1';
else
bits[31 - i] = '0';
}
return bits;
}
unsigned int leftRotate(unsigned int intArg, unsigned int rotAmt)
{
return (intArg << rotAmt) | (intArg >> (32 - rotAmt));
}
unsigned int oddParitySet3(unsigned int intArg, unsigned int startBit){
unsigned int mask = 0x00000007;
unsigned int shiftedMask = mask << startBit;
unsigned int temp = intArg & shiftedMask;
unsigned int result = intArg;
if(__builtin_popcount(temp) % 2 == 0)
result |= shiftedMask;
else
result &= ~shiftedMask;
return result;
}
need help to fix the oddParitySet3 function so that it does not display errors that are in the photo.
int X = 0x1234ABCD;
int Y = 0xcdba4321;
// a) print the lower 10 bits of X in hex notation
int output1 = X & 0xFF;
printf("%X\n", output1);
// b) print the upper 12 bits of Y in hex notation
int output2 = Y >> 20;
printf("%X\n", output2);
I want to print the lower 10 bits of X in hex notation; since each character in hex is 4 bits, FF = 8 bits, would it be right to & with 0x2FF to get the lower 10 bits in hex notation.
Also, would shifting right by 20 drop all 20 bits at the end, and keep the upper 12 bits only?
I want to print the lower 10 bits of X in hex notation; since each character in hex is 4 bits, FF = 8 bits, would it be right to & with 0x2FF to get the lower 10 bits in hex notation.
No, that would be incorrect. You'd want to use 0x3FF to get the low 10 bits. (0x2FF in binary is: 1011111111). If you're a little uncertain with hex values, an easier way to do that these days is via binary constants instead, e.g.
// mask lowest ten bits in hex
int output1 = X & 0x3FF;
// mask lowest ten bits in binary
int output1 = X & 0b1111111111;
Also, would shifting right by 20 drop all 20 bits at the end, and keep the upper 12 bits only?
In the case of LEFT shift, zeros will be shifted in from the right, and the higher bits will be dropped.
In the case of RIGHT shift, it depends on the sign of the data type you are shifting.
// unsigned right shift
unsigned U = 0x80000000;
U = U >> 20;
printf("%x\n", U); // prints: 800
// signed right shift
int S = 0x80000000;
S = S >> 20;
printf("%x\n", S); // prints: fffff800
Signed right-shift typically shifts the highest bit in from the left. Unsigned right-shift always shifts in zero.
As an aside: IIRC the C standard is a little vague wrt to signed integer shifts. I believe it is theoretically possible to have a hardware platform that shifts in zeros for signed right shift (i.e. micro-controllers). Most of your typical platforms (Intel/Arm) will shift in the highest bit though.
Assuming 32 bit int, then you have the following problems:
0xcdba4321 is too large to fit inside an int. The hex constant itself will actually be unsigned int in this specific case, because of an oddball type rule in C. From there you force an implicit conversion to int, likely ending up with a negative number.
Y >> 20 right shifts a negative number, which is non-portable behavior. It can either shift in ones (arithmetic shift) or zeroes (logical shift), depending on compiler. Whereas right shifting unsigned types is well-defined and always results in logical shift.
& 0xFF masks out 8 bits, not 10.
%X expects an unsigned int, not an int.
The root of all your problems is "sloppy typing" - that is, writing int all over the place when you actually need a more suitable type. You should start using the portable types from stdint.h instead, in this case uint32_t. Also make a habit of always ending you hex constants with a u or U suffix.
A fixed program:
#include <stdio.h>
#include <stdint.h>
int main (void)
{
uint32_t X = 0x1234ABCDu;
uint32_t Y = 0xcdba4321u;
printf("%X\n", X & 0x3FFu);
printf("%X\n", Y >> (32-12));
}
The 0x3FFu mask can also be written as ( (1u<<10) - 1).
(Strictly speaking you need to printf the stdint.h types using specifiers from inttypes.h but lets not confuse the answer by introducing those at the same time.)
Lots of high-value answers to this question.
Here's more info that might spark curiosity...
int main() {
uint32_t X;
X = 0x1234ABCDu; // your first hex number
printf( "%X\n", X );
X &= ((1u<<12)-1)<<20; // mask 12 bits, shifting mask left
printf( "%X\n", X );
X = 0x1234ABCDu; // your first hex number
X &= ~0u^(~0u>>12);
printf( "%X\n", X );
X = 0x0234ABCDu; // Note leading 0 printed in two styles
printf( "%X %08X\n", X, X );
return 0;
}
1234ABCD
12300000
12300000
234ABCD 0234ABCD
print the upper 12 bits of Y in hex notation
To handle this when the width of int is not known, first determine the width with code like sizeof(unsigned)*CHAR_BIT. (C specifies it must be at least 16-bit.)
Best to use unsigned or mask the shifted result with an unsigned.
#include <limits.h>
int output2 = Y;
printf("%X\n", (unsigned) output2 >> (sizeof(unsigned)*CHAR_BIT - 12));
// or
printf("%X\n", (output2 >> (sizeof output2 * CHAR_BIT - 12)) & 0x3FFu);
Rare non-2's complement encoded int needs additional code - not shown.
Very rare padded int needs other bit width detection - not shown.
I need to write a macro named CountBitsM. this macro has one parameter and produces a value of type int. The parameter is any expression with an object data type or the literal name of any object data type, so i used int. This macro determines the number of bits of storage used for the data type on any machine in which its run. And i can use a macro from limits.h. Here is what i wrote, does this look right?
#ifndef COUNTBITSM_H
#define COUNTBITSM_H
#include <limits.h>
#define CountBitsM(int) ((int)*(CHAR_BIT))
#endif
Second question was to create a function CountIntBitsF that counts the number of bits used to represent a type int value on any machine. However, i can NOT USE any #define, or #include header files, or any macro. I also can not use any multiplications or divisions. The hint that was given was to start with a value of 1 in a type unsigned int variable and left-shift it one bit at a time, keeping count of number of shifts, until the variables value becomes 0. Here is what i have so far:
int CountIntBitsF(void)
{
int IntgMax = 8;
unsigned int count = 1;
while (IntgMax = IntgMax>>2) count++;
return count;
}
First off, i am not supposed to use division or multiplication so am i doing the shift properly? And i cant assume a char/byte contains 8 or any other specific number of bits. So how or what should i set my IntgMax to? Thanks for any help. I am new to C.
Macro for Bits in a Type
A macro to produce the number of bits used to represent a type in storage is:
#define CountBitsM(x) (sizeof (x) * CHAR_BIT)
However, this produces a result with type size_t (usually). If you really need an int result as stated in the question, convert it (but be aware overflow becomes possible):
#define CountBitsM(x) ((int) (sizeof (x) * CHAR_BIT))
Counting Bits
The second question asks to count the number of bits “to represent a type int value” by shifting bits in an unsigned value. There are two theoretical problems here. One is that the number of bits used to represent a value may including padding bits, and counting the bits by shifting a 1 through them only counts the value bits, not the padding bits. The second is that an int may have more padding bits than an unsigned; it may use fewer bits for the sign and value. Overwhelmingly, modern systems will not have these issues; the number of used bits in an int will be the same as the total number of bits used to store it and the number of bits used in an unsigned.
That said, you can count the number of bits in an unsigned object with:
int count = 0;
for (unsigned u = 1; 0 != u; u <<= 1)
++count;
This repeatedly shifts the bit in u left until it is shifted out, while counting the number of iterations required to do this. Note that the bits in an int cannot properly be counted this way, because the behavior of left shift is not defined by the C standard when it overflows an int.
Question one
#define NBITS(type_or_object) (sizeof(type_or_object) * CHAR_BIT)
or without multiplication
#define NBITS(type_or_object) (sizeof(type_or_object) << (CHAR_BIT == 8 ? 3 : CHAR_BIT == 16 ? 4 : CHAR_BIT == 32 ? 5 : 0))
Second question:
For the most popular two's complement (but I think it will also work for sign bit as well as -0 < 0 as I remember). Ir is for signed type. Unsigned types are easy.
int CountIntBits(void)
{
int IntgMax = 1;
int count = 1;
while (IntgMax > 0 )
{
count++;
IntgMax <<= 1;
}
return count;
}
int main(void)
{
printf("%d\n", CountIntBits());
}
or (also no multiplication :) )
int CountIntBits(void)
{
int shift = CHAR_BIT == 8 ? 3 : CHAR_BIT == 16 ? 4 : CHAR_BIT == 32 ? 5 : 0;
return sizeof(int) << shift;
}
for unsigned types:
int CountIntBits(void)
{
unsigned IntgMax = 1;
int count = 0;
while (IntgMax)
{
count++;
IntgMax <<= 1;
}
return count;
}
If I have an int a, which is lets say equal to 0.
Is there a way for me to say left shift 101 into the variable and then in another step shift in 011 into it? Then I could get the int decimal number at the end? It would end up becoming 0b00000000000000000000000000101011.Or should I only use the OR operation.
You can't shift bits into the variable; you can OR them in:
int a = 0;
a |= 5;
printf("a = %d\n", a);
a <<= 3;
a |= 3;
printf("a = %d\n", a);
If your system supports binary constants, you can use those instead of decimals (and you can prefix 5 and 3 with 0 for octal or 0x for hexadecimal if you prefer — and you can print with a different format according to taste, too). If the starting value for a isn't known to be 0, you would do a shift-assignment operation before the first |= operation.
Eventually, you have to worry about left-shifting a signed integer value such that overflow occurs — that leads to undefined behaviour. It isn't a problem with the values in the question, though.
You would need to first shift by the required number of bits then perform a bitwise OR of the new data.
int a = 0;
a = a << 3;
a = a | 0x5;
a = a << 3;
a = a | 0x3;
printf("a=%x\n", a);
( Used separate assignments and operators instead of compound operators to make it clearer to beginners. )
Result:
a=2b
Is there a way for me to say left shift 101 into the variable
No. You need to left shift first, then add (or OR) the new value.
int eax = 0;
eax <<= 3;
eax |= 5;
int a = 0;
a << 3;
a |= 0x5;
a << 3;
a |= 0x3;
There isn't a predefined way to "shift in" a value like that. It wouldn't take much time to write a function that could though.
There is - to my knowledge - no operation that "shifts" a number of bits from one integer into another. The left shift operator always fills the arising spaces with 0, such that you have to combine it with, for example, an |-operation (actually a + would have the same effect in your case).
#include <stdio.h>
void printBinary(int b, int nrOfBits) {
for (int mask = (1 << nrOfBits); mask != 0; mask >>=1 ) {
char c = (b & mask) ? '1' : '0';
printf("%c", c);
}
}
int main()
{
int a = 0;
a = (a << 3) | 0x5;
printBinary(a, 8);printf("\n");
a = (a << 3) | 0x3;
printBinary(a, 8);printf("\n");
return 0;
}
When using left shift operators on signed datatypes be careful not to produce undefined behaviour (cf. cppreference concerting arithmetic operations):
When signed integer arithmetic operation overflows (the result does
not fit in the result type), the behavior is undefined
I have a big char *str where the first 8 chars (which equals 64 bits if I'm not wrong), represents a bitmap. Is there any way to iterate through these 8 chars and see which bits are 0? I'm having alot of trouble understanding the concept of bits, as you can't "see" them in the code, so I can't think of any way to do this.
Imagine you have only one byte, a single char my_char. You can test for individual bits using bitwise operators and bit shifts.
unsigned char my_char = 0xAA;
int what_bit_i_am_testing = 0;
while (what_bit_i_am_testing < 8) {
if (my_char & 0x01) {
printf("bit %d is 1\n", what_bit_i_am_testing);
}
else {
printf("bit %d is 0\n", what_bit_i_am_testing);
}
what_bit_i_am_testing++;
my_char = my_char >> 1;
}
The part that must be new to you, is the >> operator. This operator will "insert a zero on the left and push every bit to the right, and the rightmost will be thrown away".
That was not a very technical description for a right bit shift of 1.
Here is a way to iterate over each of the set bits of an unsigned integer (use unsigned rather than signed integers for well-defined behaviour; unsigned of any width should be fine), one bit at a time.
Define the following macros:
#define LSBIT(X) ((X) & (-(X)))
#define CLEARLSBIT(X) ((X) & ((X) - 1))
Then you can use the following idiom to iterate over the set bits, LSbit first:
unsigned temp_bits;
unsigned one_bit;
temp_bits = some_value;
for ( ; temp_bits; temp_bits = CLEARLSBIT(temp_bits) ) {
one_bit = LSBIT(temp_bits);
/* Do something with one_bit */
}
I'm not sure whether this suits your needs. You said you want to check for 0 bits, rather than 1 bits — maybe you could bitwise-invert the initial value. Also for multi-byte values, you could put it in another for loop to process one byte/word at a time.
It's true for little-endian memory architecture:
const int cBitmapSize = 8;
const int cBitsCount = cBitmapSize * 8;
const unsigned char cBitmap[cBitmapSize] = /* some data */;
for(int n = 0; n < cBitsCount; n++)
{
unsigned char Mask = 1 << (n % 8);
if(cBitmap[n / 8] & Mask)
{
// if n'th bit is 1...
}
}
In the C language, chars are 8-bit wide bytes, and in general in computer science, data is organized around bytes as the fundamental unit.
In some cases, such as your problem, data is stored as boolean values in individual bits, so we need a way to determine whether a particular bit in a particular byte is on or off. There is already an SO solution for this explaining how to do bit manipulations in C.
To check a bit, the usual method is to AND it with the bit you want to check:
int isBitSet = bitmap & (1 << bit_position);
If the variable isBitSet is 0 after this operation, then the bit is not set. Any other value indicates that the bit is on.
For one char b you can simply iterate like this :
for (int i=0; i<8; i++) {
printf("This is the %d-th bit : %d\n",i,(b>>i)&1);
}
You can then iterate through the chars as needed.
What you should understand is that you cannot manipulate directly the bits, you can just use some arithmetic properties of number in base 2 to compute numbers that in some way represents some bits you want to know.
How does it work for example ? In a char there is 8 bits. A char can be see as a number written with 8 bits in base 2. If the number in b is b7b6b5b4b3b2b1b0 (each being a digit) then b>>i is b shifted to the right by i positions (in the left 0's are pushed). So, 10110111 >> 2 is 00101101, then the operation &1 isolate the last bit (bitwise and operator).
If you want to iterate through all char.
char *str = "MNO"; // M=01001101, N=01001110, O=01001111
int bit = 0;
for (int x = strlen(str)-1; x > -1; x--){ // Start from O, N, M
printf("Char %c \n", str[x]);
for(int y=0; y<8; y++){ // Iterate though every bit
// Shift bit the the right with y step and mask last position
if( str[x]>>y & 0b00000001 ){
printf("bit %d = 1\n", bit);
}else{
printf("bit %d = 0\n", bit);
}
bit++;
}
}
output
Char O
bit 0 = 1
bit 1 = 1
bit 2 = 1
bit 3 = 1
bit 4 = 0
bit 5 = 0
bit 6 = 1
bit 7 = 0
Char N
bit 8 = 0
bit 9 = 1
bit 10 = 1
...