views:

378

answers:

4

I'm in the process of porting some ANSI C++ code to C#... and this is killing me right now.

Both tests have value = 6844268.

Test code:

value >> 12
value & 0x00000FFF

C++ returns 18273 and 29497, whereas C# returns 1670 and 3948. I've tried every possible combination of types in C# (int, uint, long, ulong, Int64...), but no go :(

Original value in C++ is unsigned int. Anyone have any ideas?

EDIT: Argh, I messed up my debugging. Was looking at array[value] instead of value. My bad.

+3  A: 

I don't know what C++ is up to, but on my calculator the C# values are correct; is this possibly a sign extension problem (the C++ value is negative, and the shifting is dragging the top 1 bit with it??)

Also, given that 0xFFF is 4095, there is no way the & operation can return a value larger than that.

Software Monkey
In that case, wouldn't 68844268>>12 and 18237 line up bit-wise, just with a different set of topmost bits? The way I see it, they don't, so it looks unlikely that he's actually bitshifting down 12 times. *Looks* being the operative word here :)
Lasse V. Karlsen
Good catch on the AND-operation, I didn't even look at that!
Lasse V. Karlsen
Yep, the sign extension was just an "out there" thought that occurred to me as I was typing. I didn't think about it really hard.
Software Monkey
+4  A: 

Check your C++ definitions for overridden >> operator code perhaps?

C# is calculating the right values, are you absolutely 100% sure your values are what you say they are?

Just to go through the motions:

6844268 = 11010000110111101101100
>> 12   =             11010000110.111101101100
result  =             11010000110
result  = 2 + 4 + 128 + 512 + 1024 = 1670

  18273       =   100011101100001
6844268 >> 12 =       11010000110
                        ^^^^  ^^^ <-- mismatches

they don't line up, there must be some details you're not seeing in your code there.

Lasse V. Karlsen
A: 

No overridden >> operator. This is the relevant C++ code snippet:

[Function signature: const unsigned char *src, int len, char *dst]
unsigned short *sdst = (unsigned short*) dst;
unsigned short *slt = (unsigned short*) lookup_ext;

while (len >= 3) {
    unsigned int value = *src++ << 16;
    value |= *src++ << 8;
    value |= *src++;

    cout << value << endl;
    *sdst++ = slt[value >> 12];
    *sdst++ = slt[value & 0x00000FFF];

    cout << sizeof(unsigned short) << endl << slt[value >> 12] << endl << slt[value & 0x00000FFF] << endl;
    len -= 3;
}

cout's added for wolf fence debugging.

cout output:

6844268 | cout << value
2 | sizeof(unsigned short)
18273 | slt... Ohhhh sneaky. I mis-pasted that, nevermind - it's an slt issue [Output's the same now]
29497
hb
Lasse V. Karlsen
I get the values I wrote in the first post. I'll update it in a min.
hb
+1  A: 

Seems correct to me ...

sock@thebrain:~$ g++ test.cc
sock@thebrain:~$ ./a.out
6844268 1670 1670
6844268 1670 1670

sock@thebrain:~$ cat test.cc
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
unsigned int value = 6844268;
printf("%u %u %u\n", value, value >> 12, (value >> 12)&0xFFF);
cout << value << " ";
cout << (value>>12) << " ";
value = (value>>12)&0xFFF;
cout << value << endl;
return 0;
};
Rob Elsner