Below is a program in which I am trying to reset a particular bit of a hexadecimal number. The bit location, number of bits to reset, and hexadecimal value all are user inputs.
Header file
#pragma once
int bit0(int i,unsigned int RegA,unsigned int RegB,int s[]);
C file
#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "iostream"
#include "targetver.h"
#include "bit.h"
int bit0(int i,unsigned int RegA,unsigned int RegB,int s[])
{
unsigned int j=0;
unsigned int K=0;
unsigned int L=0;
printf("\nThe bit is at s[0] is %x\n", s[0]);
for (j=0; j<i; j++)
{
K = (1 << s[j]);
L = ~K;
RegB = RegA & ~L;
printf("\nThe bit is %x\n", RegB);
if (RegB | 0)
{
RegB = RegB & ~ (1 << s[j]);
}
else
{
RegB;
}
}
printf("\nThe new reset bit is %x\n", RegB);
_getch();
return 0;
}
main file
#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "iostream"
#include "targetver.h"
#include "bit.h"
int main()
{
int i=0;
int j=0;
int s[35]={0};
unsigned int RegA = 0;
unsigned int RegB = 0;
printf("Enter the hexa decimal value to be reset ");
scanf_s("%x", &RegA);
printf("Entered hexa decimal value is %x ", RegA);
printf("\nHow many decimal places needs to be reset (0-31) ?");
scanf_s("%d", &i);
printf("Enter the decimal places that needs to be reset ");
for (j=0; j<i; j++)
{
scanf_s("%d", &s[j]);
}
///// check the entered hex value on those decimals places as bit 0 or bit 1
bit0(i,RegA,RegB,s);
_getch();
return 0;
}
I am compiling and running executing the above code using Visual Studio.
The problem is in the C file, on the RegB = RegA & ~L; line. The AND operation seems not to be taking place because I am getting 0 as the RegB value.
Program input:
Enter the hexadecimal value to be reset : 0100 1111
Entered hexadecimal value is : 0100 1111
How many decimal places needs to be reset (0-31): 1
Enter the decimal places that needs to be reset : 1
Well of course you get 0, but that's because the
&operations you have written are (all) being performed. Here's the relevant section of your code:Before we continue, though, there are quite a few opportunities to simplify:
Ljust complicates things for me; I'd rather just see~KRegB | 0is eqivalent to simplyRegBelseblock does nothingifblock can safely be executed unconditionally, in the sense that nothing will change if it is executed when the given condition is false.K = (1 << s[j])and do not afterward change it, you later repeat yourself by using the expression(1 << s[j])instead of just sayingK.printf()may have some utility for debugging, but it slightly obscures the details of the computationThis equivalent code will be easier to reason about:
And at that point the problem should be crystal clear: no matter what the value of
RegAis, as long ass[j]is between 0 and 30,* you computeRegBby first masking off some ofRegA's bits, and then masking off the remaining ones. Naturally, the result is always 0.*Because
1is a signed integer constant, if the implementation'sints are 32 bits wide, left-shifting by 31 places produces an out-of-range result. As far as the standard is concerned, the resulting behavior is undefined. It would be better to avoid this issue by using an unsigned constant, i.e.1U.