C #: Não é possível converter de ulong a byte
-
22-08-2019 - |
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:
- ulong Mut1 = GenerateValue (mut);
- 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!
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) );