0

I've checked the questions that were already posted and couldn't quite find the solution to my problem...

I'm making a console program that inputs 2 variables: 1 is a byte and the other is a number of the bit I need to get from that byte using only masking and if statements.

int E1 () {
    unsigned char a, b, c;

    printf("Number (byte):");
    scanf("%d", &a);
    a= (unsigned char)a;
    printf("\n Bit you want to output (between 0 and 7) :");
    scanf("%d", &b);
    b=(unsigned char)pow((float)2.0,b);
    printf("Mask is: %d", b);
    c= a & b; //<-- This returns 0
    if (c>0) {
    printf("\n\nThe bit is: 1");
    }
    else {
        printf("\n\nThe bit is: 0");
    }
    return 0;
}

I've asked my teacher and he said that it should work fine. I've tried it and it doesn't work. He is using Visual Studio Express, the free version one can get from Microsoft website and I'm using Code::Blocks (in case this makes a difference in the results).I've added a comment to where I think the problem lies but not sure.

Can anybody please help me with this. Thanks in advance.

user3521388
  • 73
  • 1
  • 3
  • 6

3 Answers3

3

Use 1<<b as the mask. Not only is it idiomatic, it's also hugely more efficient than using floating-point calculations. So delete this line:

b=(unsigned char)pow((float)2.0,b);

And set c like this:

c = a & (1<<b)

Does that work any better?

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
2

Some testing tells me it's this part that's wrong:

scanf("%d", &a);

This is in fact undefined behavoir: it may or may not work, but you can't really rely on anything. This is because while a is only a 1-byte char, while %d expects a 4-byte integer, meaning that scanf writes four bytes of memory instead of one.

This has the unfortunate side effect that the second call (to scanf("%d", &b)) might use the memory where some other variables in your program are stored, in this case, a. This gets overwritten and set to 0, leading to the expression 0 & b which of course evaluates to 0.

The proper way to solve this problem is to use %hhd instead of %d, which makes scanf expect a char instead of an int, and only write 1 byte of memory.


Side notes about your code

  • The line a = (unsigned char) a; is useless, since a is already of type unsigned char.
  • As Graham noted in his answer, you should use b = (1 << b); when calculating powers of two, since this is much more pretty code and also much more efficient — many modern CPUs can do this in just one instruction.
Community
  • 1
  • 1
Frxstrem
  • 38,761
  • 9
  • 79
  • 119
  • Ok so I've tried the changes you suggested and this time I've tried running the debugger. Apparently its as you said: its taking more bytes than it should. The first time I run scanf it saves the value 200 in the variable 'a'. The second time it saves the second value 3 in the other variable 'b', but its overwriting the variable 'a' as 0 (Note: I'm using "%hhd" in the scanf function). Anybody know how to make it stop from doing that? Maybe its that I'm using x64 OS? – user3521388 Apr 11 '14 at 18:25
  • You're using `scanf("%hhd", &b)` as well? Then it shouldn't really be overwriting anything. The fact that you're using a 64-bit OS shouldn't really matter much if your code is well-defined behavior. – Frxstrem Apr 11 '14 at 19:42
  • Here's a fixed version of your code, which I'm pretty sure should work fine (does for me, at least): https://gist.github.com/anonymous/346d631814c54fb90263 – Frxstrem Apr 11 '14 at 19:51
  • Copied your code and compiled it. Tried with the number 200 and and bit 3 which should be '1' and it output '0'. Are you using a x32 OS or a x64 OS? – user3521388 Apr 12 '14 at 00:59
  • Are you using Windows? Because if you do, [that may be part of the problem](http://stackoverflow.com/a/15825386). The easiest solution to fix this, though, is just to use a larger data type – like `int` instead of `unsigned char` – and then `scanf("%d", &a)` should work properly as well. – Frxstrem Apr 13 '14 at 20:24
0
printf("The bit is: %d", 1 & a>>b);