views:

214

answers:

6

I need to convert this code (in C++) into Java code :

    short i;
    short j;
    short k;
    short result;
    unsigned short  m_table[ 256 ]

    for ( i = 0 ; i < 256 ; i++ )
    {
        k = i << 8;
        result = 0;
        for ( j = 0 ; j < 8 ; j++ )
        {
            if ( ( result^ k ) & 0x8000 )   
                result= ( result<< 1 ) ^ 0x1021;
            else
                result<<= 1;
            k <<= 1;
        }
        m_table[ i ] = (unsigned short) result;
    }

...but I never get the same result...

My Java code is:

int i;
int j;
int k;
int result;
int m_table[ 256 ] = new int[256];

for ( i = 0 ; i < 256 ; i++ ) {
    k = (i << 8);

    result = 0;

    for ( j = 0 ; j < 8 ; j++ ) {

        if ( (( result^ k ) & 0x8000) != 0)
            result= (( result<< 1 ) ^ 0x1021);
        else
            result<<= 1;

        k <<= 1;
    }

    m_table[ i ] = (result);
}
+5  A: 

You need to be careful in Java with bit operations. Java does not have any unsigned types, so you probably need to go one type size bigger than what you would use with the unsigned variety.

Matt Moriarity
That's a good point. In this case, `unsigned short` should probably be replaced with `int`. Other than that, I think that C++ is all valid Java.
Thomas Owens
+1  A: 

Is the JVM big-endian? What happens if you use the constants 0x0080 and 0x2110?

Matt
A discussion on the endianness of the JVM: http://www.velocityreviews.com/forums/t548186-endianness-of-java-virtual-machine.html
Thomas Owens
@Thomas: A simple "yes" or "no" would suffice. ;)
jalf
I think the discussion was linked instead of an answer since the question is a bit of a loaded one in the case of Java.
Matt Moriarity
@jalf how about "neither"?
Jesper
+1  A: 

Java does integer operations on ints or longs (if present), so you'll need to case the results back to short. Also there is no automatic conversion from integers to booleans. Leaving out braces is a bit taboo. So:

        if ( ( result^ k ) & 0x8000 )   
            result= ( result<< 1 ) ^ 0x1021;
        else
            result<<= 1;

Should become:

        if (((result^k) & 0x8000) == 0) {
            result <<= 1;
        } else {
            result = (short)((result<<1) ^ 0x1021);
        }

The unsigned from unsigned short should go (no almost unsigned in Java, although you could use char). Java has the advantage of having reliable ranges and behaviour of integer types. Stick to using short if you mean 16-bits. The top 16-bits will be removed, but careful when reading out to & 0xffff. The original C (or "C++") code is not portable.

Tom Hawtin - tackline
+2  A: 

As others have stated, upping the size of m_table is a solution. However, you will need to be careful in the casting to keep it unsigned.

Simply doing:

m_table[ i ] = (int)result;

...for example, will carry over the sign bit of result. So if the signed short result was -1 then m_table[i] will end up with -1 when what you really want is 0xffff.

Fix that with:

m_table[ i ] = result & 0xffff;

That should give you the equivalent of the original signed short to unsigned short cast... storing it in an int just to maintain the unsigned-ness.

PSpeed
A: 

thanks for all yours answers... but it doesn't work...

Arutha
A: 

The problem you have I believe is with left shifting( << ) int values out of unsigned short range. To remedy the problem you need to mask the result of left shift into the range. The mask to use is 0xFFFF. The thing to remember is that & is a very low precedence operator, so parenthesis (a lot of them) are in order. Here is the modified example.

    final int m_table[ ] = new int[256];

    for ( int i = 0 ; i < 256 ; i++ ) {
        // OK not to mask the result of << here, we are in unsigned short range
        int k = (i << 8); // BTW, terrible name for this variable

        int result = 0;

        for ( int j = 0 ; j < 8 ; j++ ) {

            if ( (( result^ k ) & 0x8000) != 0)
            {
                result= (( (result<< 1) & 0xFFFF ) ^ 0x1021);
            }
            else
            {
                result <<= 1;     // Change to 1-liner if you wish
                result &= 0xFFFF; //
            }

            k <<= 1;     // Change to 1-liner if you wish
            k &= 0xFFFF; //
        }

        m_table[ i ] = result;
    }
Alexander Pogrebnyak