2

C++ではできるのに、C#ではできないのは奇妙なことです。

明確にするために、2 つの関数を C++ に貼り付けてから C# に貼り付け、C# コードの問題のある行にコメント「//error」を付けます。2 つの関数が行うことは、パラメーターをエンコードしてから、それを byte1seeds という名前のグローバル変数に追加することです。

これらはC++の関数です

//Global var:

unsigned char byte1seeds[3];

unsigned long GenerateValue( unsigned long * Ptr )
{
unsigned long val = *Ptr;
for( int i = 0; i < 32; i++ )
    val = (((((((((((val >> 2)^val) >> 2)^val) >> 1)^val) >> 1)^val) >> 1)^val)&1)|((((val&1) << 31)|(val >> 1))&0xFFFFFFFE);
return ( *Ptr = val );
}

void SetupCountByte( unsigned long seed )
{
if( seed == 0 ) seed = 0x9ABFB3B6;
unsigned long mut = seed;
unsigned long mut1 = GenerateValue( &mut );
unsigned long mut2 = GenerateValue( &mut );
unsigned long mut3 = GenerateValue( &mut );
GenerateValue( &mut );
unsigned char byte1 = (mut&0xFF)^(mut3&0xFF);
unsigned char byte2 = (mut1&0xFF)^(mut2&0xFF);
if( !byte1 ) byte1 = 1;
if( !byte2 ) byte2 = 1;
byte1seeds[0] = byte1^byte2;
byte1seeds[1] = byte2;
byte1seeds[2] = byte1;
}

今C#コード:

関数 GenerateValue を変更しました。パラメーターとしてポインターを持つ代わりに、ulong パラメーターがあります。

それを呼び出して両方の値を変更するには、次を使用します。

  1. ulong mut1 = GenerateValue(mut);
  2. mut = mut1;

翻訳された関数は次のとおりです (問題のある行は「//エラー」でマークされています)。

//Global var:
public static byte[] byte1seeds = new byte[3];

public static ulong GenerateValue(ulong val)
{
    for( int i = 0; i < 32; i++ )
        val = (((((((((((val >> 2)^val) >> 2)^val) >> 1)^val) >> 1)^val) >> 1)^val)&1)|((((val&1) << 31)|(val >> 1))&0xFFFFFFFE);
    return val ;
}

public static void SetupCountByte( uint seed )
{
    if( seed == 0 ) seed = 0x9ABFB3B6;
    ulong mut = seed;
    ulong mut1 = GenerateValue(mut);
    mut = mut1;
    ulong mut2 = GenerateValue(mut);
    mut = mut2;
    ulong mut3 = GenerateValue(mut);
    mut = mut3;
    mut = GenerateValue(mut);
    byte byte1 = (mut & 0xFF) ^ (mut3 & 0xFF); //error
    byte byte2 = (mut1 & 0xFF) ^ (mut2 & 0xFF); //error
    if( byte1 != 0 )
        byte1 = 1;
    if( byte2 != 0 )
        byte2 = 1;
    byte1seeds[0] = byte1^byte2; //error
    byte1seeds[1] = byte2;
    byte1seeds[2] = byte1;
}

エラーは次のとおりです。

タイプ 'ulong' を 'byte' に暗黙的に変換することはできません。明示的な変換が存在します (キャストがありませんか?)

編集:問題のある3行目のエラーは次のとおりです:

タイプ 'int' を 'byte' に暗黙的に変換することはできません。明示的な変換が存在します (キャストがありませんか?)

ここで質問があります: これらのエラーを解決するにはどうすればよいですか?

前もって感謝します!

4

5 に答える 5

11

a を追加し(byte)てキャストします。精度が失われる可能性があるため、値がバイトに収まることをコンパイラに伝える必要があります。

byte byte1 = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
byte byte2 = (byte)((mut1 & 0xFF) ^ (mut2 & 0xFF));
于 2009-03-26T13:19:53.110 に答える
2

情報を失う可能性があります。コンパイラは、明示的に指示しない限り、この種の操作を許可しません。だから、次のようなことを試してください:

byte result = ((byte)mut & 0xFF) ^ ((byte)mut3 & 0xFF);

このように、すべての変数が明示的にキャストされ、結果はバイトになります。または、これを行うことができます:

byte result = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
于 2009-03-26T13:20:36.680 に答える
2

症状

次のコードは C++ でコンパイルされますが、C# コンパイラによって拒否され、3 行目で型の非互換性が報告されます。

ulong mut = 5;
ulong mut3 = 6;
byte foo = (mut & 0xFF) ^ (mut3 & 0xFF);

説明

(mut & 0xFF) ^ (mut3 & 0xFF)は型ulongであり、型の変数に代入できませんbyte

変数mutulong. のすべてのオーバーロードは&オペランド型の対称性を必要とするため、式(mut & 0xFF)では値0xFFが に昇格されulong、演算の結果の型は になりulongます。

同様のプロセスで 2 番目の部分式にも type が与えられますがulong、これは偶発的です。なぜなら、より大きな式では、expressionが typeを持ってA ^ Bいるという事実が expressionの昇格を引き起こすからです。AulongB

したがって、式(mut & 0xFF) ^ (mut3 & 0xFF)は型ulongであり、型の変数に割り当てる前に明示的なキャストが必要byteです。

解決

割り当ての前に式全体を明示的に型キャストします。

備考

ほとんどの C+ ライブラリには欠陥がたくさんあるため、人々は警告について考える代わりに警告をオフにします。警告を元に戻すと、混乱のどこかに「損失の可能性がある暗黙の型キャストが必要である」という効果のメモがあるにもかかわらず、非常に多くの警告が表示され、それらを通り抜けようとしても役に立ちません。

特に演算子に関して C# 言語仕様を読むと、非常に多くの有用なことを学ぶことができます。たとえば、次のコードは失敗します。

byte b = 0xF0 | 0x0E; //b should contain 0xFE

しかし、これらは成功します:

byte b1 = (byte)(0xF0 | 0x0E); //typecast fixes it
byte b2 = 0xF0;
b2 |= 0x0E; //reflexive operator typed by target variable
于 2009-03-26T14:04:34.250 に答える
1

明示的なダウンキャストの必要性について詳しく説明しているMSDN ナレッジ ベースの記事があります。エラー メッセージ内の "明示的な変換が存在します" という言葉は、キャストを使用してデータ型を明示的に変換する必要があることを示すことを目的としています。あなたの特定のケースでは、次のようになります。

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
于 2009-03-26T13:35:06.660 に答える
1

「明示的な変換が存在します」は、明示的なキャストを行う必要があることを示します。この場合、次のようになります。

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
byte byte2 = (byte) ( (mut1 & 0xFF) ^ (mut2 & 0xFF) );
于 2009-03-26T13:20:48.973 に答える