Как корректно записать Cardinal из Delphi (он же unsigned int из C++) в C#?

Рейтинг: 0Ответов: 1Опубликовано: 16.01.2023

Есть строка из delphi:

      var Mask: Cardinal;
      Mask := -(Result and 1);
      Result := (Result shr 1) xor (Mask and $FF242143);

При написании её в C#:

      uint mask;
      uint result = 0;
      mask = -(result & 1);
      result = (result>>1) ^ (mask & 0xFF242143);

Выводит ошибку:

Не удается неявно преобразовать тип "long" в "uint". Существует явное преобразование (возможно, пропущено приведение типов)

Ответы

▲ 1Принят

Cardinal из Delphi это по сути uint в C#.

  • int и uint в C# - 4-байтовые целые числа
  • long и ulong - 8-байтовые

Вы пытаетесь привести 8-байтовое число со знаком к 4-байтовому числу без знака. Так как такой каст может повлечь за собой частичную потерю данных, его нельзя выполнять неявно. Но можно кастануть явно поставив (uint) перед переменной.

Так как uint беззнаковое целое, при попытке изменить ему знак, C# подбирает наиболее подходящий тип с неявным приведением, в данном случае long.

На мой взгляд, стоит избежать каста к 8-байтовым типам, чтобы не нарушить двоичную логику. А так же закастовать результат обратно в uint.

uint result = 0;
uint mask = (uint)-((int)result & 1); // если навести мышку на оператор &, студия покажет, для каких типов он выполнится.
result = (result >> 1) ^ (mask & 0xFF242143);