С#:Невозможно преобразовать улонг в байт.
-
22-08-2019 - |
Вопрос
Странно, как я могу сделать это на C++, но не на C#.
Чтобы было понятно, я вставлю две функции в C++, а затем в C# и отмечу проблемные строки в коде C# комментарием «//error».Эти две функции кодируют параметр, а затем добавляют его в глобальную переменную с именем 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;
}
Теперь код С#:
Я изменил функцию GenerateValue. Вместо указателя в качестве параметра у нее есть параметр ulong.
Чтобы вызвать его и изменить оба значения, я использую:
- ulong mut1 = GenerateValue(mut);
- мут = мут1;
Вот переведенные функции (проблемные строки отмечены знаком "//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;
}
Ошибка:
Невозможно неявно преобразовать тип «ulong» в «byte».Существует явное преобразование (вам не хватает приведения?)
изменить: ошибка в проблемной строке 3:
Невозможно неявно преобразовать тип int в byte.Существует явное преобразование (вам не хватает приведения?)
Вот возникает вопрос:Как решить эти ошибки?
Заранее спасибо!
Решение
Добавить (byte)
чтобы бросить его.Поскольку вы можете потерять точность, вам придется сообщить компилятору, что значение поместится в байт, т.е.
byte byte1 = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
byte byte2 = (byte)((mut1 & 0xFF) ^ (mut2 & 0xFF));
Другие советы
Вы можете потерять информацию.Компилятор не разрешает такого рода операции, если вы явно не скажете ему об этом.Итак, попробуйте что-то вроде этого:
byte result = ((byte)mut & 0xFF) ^ ((byte)mut3 & 0xFF);
Таким образом, все переменные приводятся явно, и результатом будет байт.Или вы можете сделать это:
byte result = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
Симптом
Следующий код компилируется на C++, но отклоняется компилятором C#, а третья строка сообщает о несовместимости типов.
ulong mut = 5;
ulong mut3 = 6;
byte foo = (mut & 0xFF) ^ (mut3 & 0xFF);
Объяснение
Выражение (mut & 0xFF) ^ (mut3 & 0xFF)
имеет тип ulong
и не может быть присвоен переменной типа byte
.
Переменная mut
это ulong
.Все перегрузки &
требуют симметрии типа операнда, поэтому в выражении (mut & 0xFF)
, Значение 0xFF
повышен до ulong
, а результат операции имеет тип ulong
.
Хотя аналогичный процесс также придает второму подвыражению тип ulong
, это случайно, потому что в более широком выражении A ^ B
, тот факт, что выражение A
имеет тип ulong
вызвало бы выражение B
быть продвинутым.
Таким образом, выражение (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
«явное преобразование существует» означает, что вам необходимо выполнить явное приведение.В данном случае это будет что-то вроде:
byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
byte byte2 = (byte) ( (mut1 & 0xFF) ^ (mut2 & 0xFF) );
Есть Статья базы знаний MSDN это подробно объясняет необходимость явного принижения.Слова «существует явное преобразование» в сообщении об ошибке указывают на то, что тип данных необходимо явно преобразовать с помощью приведения.В вашем конкретном случае это будет выглядеть так:
byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );