Bitwise AND operation program execution issue

83 Views Asked by At

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

1

There are 1 best solutions below

2
John Bollinger On

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:

    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;
    }

Before we continue, though, there are quite a few opportunities to simplify:

  • variable L just complicates things for me; I'd rather just see ~K
  • RegB | 0 is eqivalent to simply RegB
  • the else block does nothing
  • the if block can safely be executed unconditionally, in the sense that nothing will change if it is executed when the given condition is false.
  • Although you have set K = (1 << s[j]) and do not afterward change it, you later repeat yourself by using the expression (1 << s[j]) instead of just saying K.
  • the printf() may have some utility for debugging, but it slightly obscures the details of the computation

This equivalent code will be easier to reason about:

    K = (1 << s[j]);
    RegB = RegA & K;
    RegB = RegB & ~K;

And at that point the problem should be crystal clear: no matter what the value of RegA is, as long as s[j] is between 0 and 30,* you compute RegB by first masking off some of RegA's bits, and then masking off the remaining ones. Naturally, the result is always 0.

*Because 1 is a signed integer constant, if the implementation's ints 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.