I've been trying to understand an error I get with the following code
bytes2bits(p,q,pixels)
u_char *p, *q;
register u_int pixels;
{
register u_char *r, a;
register u_long *l;
...
switch (*l++) {
case 0x00000000: a = 0x00; break;
case 0x00000001: a = 0x10; break;
case 0x00000100: a = 0x20; break;
case 0x00000101: a = 0x30; break;
case 0x00010000: a = 0x40; break;
case 0x00010001: a = 0x50; break;
case 0x00010100: a = 0x60; break;
case 0x00010101: a = 0x70; break;
case 0x01000000: a = 0x80; break;
case 0x01000001: a = 0x90; break;
case 0x01000100: a = 0xa0; break;
case 0x01000101: a = 0xb0; break;
case 0x01010000: a = 0xc0; break;
case 0x01010001: a = 0xd0; break;
case 0x01010100: a = 0xe0; break;
case 0x01010101: a = 0xf0; break;
default:
(void) fprintf(stderr,"bytes2bits: bad value %x\n",*--l);
exit(1);
}
......
}
My problem lies in the fact that this block of code exits with the error message
bytes2bits: bad value 1010100
I would've thought that 0x01010100 == 1010100 (Note: the fprintf is using %x as output format, so I am looking at a hexadecimal number. Also, when I test and use a printf with %d output format, I see the value 16843008 (= 16^6 + 16^4 + 16^2), which is the equivalent decimal representation of 0x01010100. The 'bad value' 1010100 output is not affected by the presence of my printf checking statement).
bytes2bits: bad value 1010100
How can I make sense of the fact that the switch statement does not recognize 1010100 as the next to last case (i.e.case 0x01010100: a = 0xe0)?
The only reasonable guess here is that on your platform the u_long
that you analyze with switch
is longer than int
/unsigned int
that you are actually printing.
For example, if u_long
is a 64 bit type and int
is a 32-bit type, then your *l++
might evaluate to 0xBAADF00D01010100
. This obviously will not match the case 0x01010100:
label. But when you are doing your printf
s with %x
specifier, you are only printing the trailing 0x01010100
portion.
Use l
prefix in format specifiers (%lx
, %ld
etc.) to print long
values to avoid such confusions in the future (assuming that u_long
is based on long
).
Maybe you are on a platform where the size of u_long is not as expected (e.g. a 64 bit word). So *l may take a value bigger than the 32-bit patterns you are testing, and the "%d" and "%x" format could truncate to 32 bit the actual value. I suggest you to print the sizeof(*l).
UPDATE: (hope I got it right this time ;-)
a= (*l & 1) << 4
| (*l & 0x100) >> 3
| (*l & 0x10000) >> 10
| (*l & 0x1000000) >> 17
;
if ( *l & 0xfefefefe) {
fprintf(stderr, "Badstuff: %lx\n", (unsigned long) *l);
exit(EXIT_FAILURE);
}
l++;
User contributions licensed under CC BY-SA 3.0