Pregunta

Es extraño cómo puedo hacerlo en C ++, pero no en C #.

Para que quede claro, voy a pegar las dos funciones en C ++ y luego en C # y marcar las líneas problemáticas en el código C # con un comentario "// error". Lo que los dos funciones hace es codificar el parámetro y luego añadirlo a una variable global byte1seeds con nombre.

Estas son las funciones en 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;
}

Ahora el código C #:

He cambiado la función GenerateValue.Instead de tener un puntero como un parámetro, que tiene un parámetro de ulong.

Para llamar y cambiar los dos valores que utilizo:

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

Aquí son las funciones traducidas (las líneas problemáticas están marcados con "// error");

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

El error es:

No se puede convertir implícitamente el tipo 'ulong' a 'bytes'. existe una conversión explícita (¿falta un yeso?)

edit: el error en la línea problemática 3 es:

No se puede convertir implícitamente el tipo 'int' a 'bytes'. existe una conversión explícita (¿falta un yeso?)

Aquí viene la pregunta: ¿Cómo resolver los errores

?

Gracias de antemano!

¿Fue útil?

Solución

Añadir un (byte) para su emisión. Como usted podría perder precisión, usted tiene que decirle al compilador que el valor se ajusta a un byte, es decir.

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

Otros consejos

Se puede perder información. El compilador no permite este tipo de operaciones a menos que explícitamente le dice que lo haga. Así que trate de algo como esto:

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

De esta manera, todas las variables se coló de forma explícita y el resultado será un byte. O bien, puede hacer esto:

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

Síntoma

El código siguiente se compila en C ++, pero es rechazado por un compilador de C #, con la incompatibilidad tercera línea de tipo de informes.

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

Explicación

El (mut & 0xFF) ^ (mut3 & 0xFF) expresión es de tipo ulong y no se puede asignar a una variable de tipo byte.

El mut variable es un ulong. Todas las sobrecargas de & requerir operando tipo de simetría, por lo que en el (mut & 0xFF) expresión, el 0xFF valor es promovido a ulong, y el resultado de la operación tiene el tipo ulong.

Mientras que un proceso similar tiene también dan la segunda subexpresión del tipo ulong, esto es incidental porque en el A ^ B expresión mayor, el hecho de que A expresión tiene el tipo ulong causaría B expresión para ser promovido.

Por lo tanto, la expresión (mut & 0xFF) ^ (mut3 & 0xFF) es de tipo ulong y requiere una conversión explícita antes de que pueda ser asignado a una variable de tipo byte.

Solución

Typecast explícitamente la expresión completa antes de la asignación.

Observaciones

Las personas apagan las advertencias en lugar de pensar en ellos porque la mayoría de bibliotecas de C + están plagados de defectos. Si cambia las advertencias de nuevo a obtener tantos que es inútil tratar de vadear a través de ellos, a pesar de que en algún lugar del desastre que habrá una nota en el sentido de "se requiere un encasillado potencialmente con pérdida implícita".

Si usted lee la especificación del lenguaje C #, con especial atención a los operadores, aprenderá muchas cosas útiles. Por ejemplo, este código se producirá un error:

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

pero éstos tendrán éxito:

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

"existe conversión explícita" indica que es necesario hacer una conversión explícita. En este caso, eso sería algo como:

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

Hay una rel="nofollow artículo de MSDN Knowledge Base que explica en profundidad la necesidad de que el abatido explícita. "Existe conversión explícita" las palabras en el mensaje de error se pretende que sea la clave que se debe convertir explícitamente el tipo de datos mediante el uso de un yeso. En su caso específico, que se vería así:

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top