Pergunta

Estranho como eu posso fazer isso em C ++, mas não em C #.

Para deixar claro, eu vou colar as duas funções em C ++ e, em seguida, em C # e marcar as linhas problemáticas no código C # com um comentário "// erro". O que os dois função faz é codificar o parâmetro e, em seguida, adicioná-lo em uma variável global byte1seeds nomeados.

Estas são as funções em 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;
}

Agora o código C #:

Eu mudei a função GenerateValue.Instead de ter um ponteiro como um parâmetro, ele tem um parâmetro ulong.

Para chamá-lo e alterar ambos os valores eu uso:

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

Aqui estão as funções traduzidas (as linhas problemáticas são marcadas com "// erro");

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

O erro é:

Não é possível converter implicitamente tipo 'ulong' para 'byte'. existe uma conversão explícita (faltam um elenco?)

edit: o erro na linha problemática 3 é:

Não é possível converter implicitamente tipo 'int' para 'byte'. existe uma conversão explícita (faltam um elenco?)

Aqui vem a pergunta: Como resolver esses erros

Agradecemos antecipadamente!

Foi útil?

Solução

Adicionar um (byte) para lançá-lo. Como você pode perder precisão, você tem que dizer ao compilador que o valor vai caber em um byte, ou seja.

byte byte1 = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
byte byte2 = (byte)((mut1 & 0xFF) ^ (mut2 & 0xFF));

Outras dicas

Você poderia perder informações. O compilador não permite esse tipo de operações, a menos que você diga a ele explicitamente a fazê-lo. Portanto, tente algo como isto:

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

Desta forma, todas as variáveis ??são explicitamente fundido e o resultado será um byte. Ou você pode fazer isso:

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

Sintoma

Os seguintes compila o código em C ++, mas é rejeitada por um compilador C #, com a terceira linha de tipo de relatórios incompatibilidade.

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

Explicação

O (mut & 0xFF) ^ (mut3 & 0xFF) expressão é do tipo ulong e não pode ser atribuído a uma variável do tipo byte.

O mut variável é um ulong. Todas as sobrecargas de & exigem tipo de simetria operando, assim, no (mut & 0xFF) expressão, o 0xFF valor é promovido a ulong, eo resultado da operação tem o tipo ulong.

Enquanto um processo semelhante também dá a segunda sub-expressão do tipo ulong, este é incidental porque no A ^ B expressão maior, o fato de que a expressão A tem o tipo ulong causaria expressão B a ser promovido.

Assim, o (mut & 0xFF) ^ (mut3 & 0xFF) expressão é do tipo ulong e requer uma conversão explícita antes que possa ser atribuído a uma variável do tipo byte.

Solução

De forma explícita typecast a expressão inteira antes da atribuição.

Observações

Pessoas desligar avisos em vez de pensar sobre eles, porque a maioria das bibliotecas C + estão cheias de defeitos. Se você alternar avisos costas para você obter tantos que é inútil tentar percorrer-los, mesmo que em algum lugar na confusão haverá uma nota para o efeito de "um typecast potencialmente perdas implícito era necessário".

Se você ler a especificação da linguagem C #, com especial destaque para os operadores, você vai aprender muitas coisas úteis. Por exemplo, este código irá falhar:

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

mas estes terão sucesso:

byte b1 = (byte)(0xF0 | 0x0E); //typecast fixes it
byte b2 = 0xF0;
b2 |= 0x0E; //reflexive operator typed by target variable

"existe conversão explícita" indica que você precisa fazer uma conversão explícita. Neste caso, que seria algo como:

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
byte byte2 = (byte) ( (mut1 & 0xFF) ^ (mut2 & 0xFF) );

Há um MSDN Knowledge Base artigo que explica em profundidade a necessidade dos abatidos explícito. As palavras "conversão explícita existe" na mensagem de erro se destinam a ser o indício de que você deve converter explicitamente o tipo de dados usando um molde. No seu caso específico, que seria algo como isto:

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top