1

このコード (C++) を Java コードに変換する必要があります。

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

...しかし、私は同じ結果を得ることはありません...

私のJavaコードは次のとおりです。

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

5 に答える 5

5

Java ではビット操作に注意する必要があります。Java には unsigned 型がないため、おそらく、unsigned の種類で使用するものよりも 1 つ大きな型サイズにする必要があります。

于 2009-10-13T17:47:18.823 に答える
2

他の人が述べているように、m_tableのサイズを大きくすることが解決策です。ただし、キャストを署名しないように注意する必要があります。

単に行う:

m_table[ i ] = (int)result;

...たとえば、結果の符号ビットを引き継ぎます。したがって、符号付きの短い結果が-1の場合、実際に必要なものが0xffffの場合、m_table[i]は-1になります。

それを修正します:

m_table[ i ] = result & 0xffff;

これにより、元のsignedshortからunsignedshortcastに相当するものが得られるはずです...unsignednessを維持するためだけにintに格納します。

于 2009-10-13T19:21:06.363 に答える
1

intJavaはsまたはs(存在する場合)に対して整数演算を実行longするため、結果をに戻す必要がありますshort。また、整数からブール値への自動変換はありません。中かっこを省略するのは少しタブーです。それで:

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

次のようになります。

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

unsignedfromは行くべきです(unsigned shortJavaではほとんど署名されていませんが、使用することはできますchar)。Javaには、整数型の信頼できる範囲と動作を持つという利点があります。short16ビットを意味する場合は使用に固執します。上位16ビットは削除されますが、に読み取るときは注意して& 0xffffください。元のC(または「C ++」)コードは移植性がありません。

于 2009-10-13T19:17:15.450 に答える
1

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

于 2009-10-13T17:50:39.073 に答える
0

あなたが抱えている問題は、左シフト(<<intの値がunsigned short範囲外であることです。この問題を解決するには、範囲への左シフトの結果をマスクする必要があります。使用するマスクは 0xFFFF です。覚えておくべきことは、これ&は非常に優先順位の低い演算子であるため、括弧 (多くの演算子) が適切であるということです。改造例はこちら。

    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;
    }
于 2009-10-14T14:05:41.373 に答える