C #: Ne peut pas convertir à l'octet ulong
-
22-08-2019 - |
Question
Étrange comment je peux le faire en C ++, mais pas en C #.
Pour préciser, je vais coller les deux fonctions en C ++ et en C # et marquer les lignes problématiques dans le code C # avec un commentaire « // erreur ». Ce que les deux fonctions n'encode le paramètre, puis l'ajouter dans une variable globale byte1seeds nommé.
Ce sont les fonctions 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;
}
Maintenant, le code C #:
J'ai changé la fonction GenerateValue.Instead d'avoir un pointeur comme paramètre, il a un paramètre ulong.
Pour appeler et changer les valeurs que j'utilise:
- ulong Mut1 = GenerateValue (mut);
- mut = Mut1;
Voici les fonctions traduites (les lignes problématiques sont marquées par « // erreur »);
//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;
}
L'erreur est:
Impossible de convertir implicitement le type « ulong » à « octet ». Il existe une conversion explicite (vous manque un casting?)
edit: l'erreur à la ligne 3 est problématique:
ne peut pas convertir implicitement le type « int » à « octet ». Il existe une conversion explicite (vous manque un casting?)
Voici venir la question: Comment résoudre ces erreurs
?Merci d'avance!
La solution
Ajouter un (byte)
pour le lancer. Comme vous pouvez perdre la précision, vous devez dire au compilateur que la valeur s'inscrira dans un octet, i.e..
byte byte1 = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
byte byte2 = (byte)((mut1 & 0xFF) ^ (mut2 & 0xFF));
Autres conseils
Vous pouvez perdre des informations. Le compilateur ne permet pas ce genre d'opérations à moins que vous lui dites explicitement de le faire. Donc, essayez quelque chose comme ceci:
byte result = ((byte)mut & 0xFF) ^ ((byte)mut3 & 0xFF);
De cette façon, toutes les variables sont explicitement et casté le résultat sera un octet. Ou vous pouvez faire ceci:
byte result = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
Symptôme
Le code suivant compile en C ++ mais est rejeté par un compilateur C #, avec l'incompatibilité de type reporting troisième ligne.
ulong mut = 5;
ulong mut3 = 6;
byte foo = (mut & 0xFF) ^ (mut3 & 0xFF);
Explication
Le (mut & 0xFF) ^ (mut3 & 0xFF)
d'expression est de type ulong
et ne peut être affecté à une variable de type byte
.
La mut
variable est un ulong
. Toutes les surcharges de &
exigent une symétrie de type d'opérande, donc dans l'expression (mut & 0xFF)
, la valeur 0xFF
est promu ulong
, et le résultat de l'opération a le ulong
type.
Alors qu'un processus similaire ne donne également la deuxième sous-expression du type ulong
, c'est accessoire parce que dans le A ^ B
d'expression plus grande, le fait que l'expression A
a le type ulong
causerait expression B
à promouvoir.
Ainsi, l'expression (mut & 0xFF) ^ (mut3 & 0xFF)
est de type ulong
et nécessite une distribution explicite avant de pouvoir être affecté à une variable de type byte
.
Solution
Explicitement Typecast l'expression entière avant la cession.
Remarques
Les gens désactivent avertissements au lieu de penser à eux parce que la plupart des bibliothèques C + sont criblés de défauts. Si vous changez les avertissements de retour sur vous tant qu'il est inutile d'essayer de patauger à travers eux, même si quelque part dans le désordre, il y aura une note à l'effet de « transtypage potentiellement implicite avec perte était nécessaire ».
Si vous lisez la spécification du langage C #, en ce qui concerne notamment les opérateurs, vous apprendrez beaucoup de choses utiles. Par exemple, ce code échouera:
byte b = 0xF0 | 0x0E; //b should contain 0xFE
mais ceux-ci réussiront:
byte b1 = (byte)(0xF0 | 0x0E); //typecast fixes it
byte b2 = 0xF0;
b2 |= 0x0E; //reflexive operator typed by target variable
« conversion explicite existe » indique que vous devez faire un casting explicite. Dans ce cas, ce serait quelque chose comme:
byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
byte byte2 = (byte) ( (mut1 & 0xFF) ^ (mut2 & 0xFF) );
Il y a un article MSDN Base de connaissances qui explique en profondeur la nécessité de baissés explicite. dans le message d'erreur Les mots « conversion explicite existe » sont destinés à être la moindre idée que vous devez convertir explicitement le type de données en utilisant un casting. Dans votre cas, cela ressemblerait à ceci:
byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );