Typecasting кардинал к одиночному
и Cardinal
и Single
являются 4 байт / 32-битными типами данных, но когда я печатаю их друг другу, я получаю Invalid Typecast
ошибка Delphi 10.1 (Берлин).
lSingleVar := Single(lCardinalVar);
Я не говорю о преобразование между двумя типами, так как это будет хранить только 23 бита кардинальных данных (фракционная часть один тип данных). Мне нужно сохранить минимум 30 бит данных в Single
переменной. У меня есть веские причины для этого (типа не может быть изменено), о котором я с удовольствием расскажу подробнее.
как мне typecast a Single
переменной?
4 ответов
Я бы сделал так:
lSingleVar := PSingle(@lCardinalVar)^;
и в противоположном направлении это будет:
lCardinalVar := PCardinal(@lSingleVar)^;
Я не могу придумать более прямого способа достичь того, что вы просите. На мой взгляд, это имеет то преимущество, что не требует каких-либо определений типа или функции.
вы можете использовать запись варианта для доступа к той же базовой памяти:
type
TConverter = record
case integer of
0 : (c: cardinal);
1 : (s: single);
end;
а затем используйте его так:
var
converter: TConverter;
lCardinalVar: cardinal;
lSingleVar: single;
converter.c := lCardinalVar;
lSingleVar := converter.s;
или с одной строкой typecast, как это:
lSingleVar := TConverter(lCardinalVar).s
вы можете написать такую функцию:
function ConvertCardinalToSingle(value: Cardinal): Single;
var AsSingle: Single absolute value;
begin
Result := AsSingle;
end;
здесь мы используем absolute
ключевое слово, которое означает: переменная value
и AsSingle
выделить одну и ту же память. Это ключевое слово считается устаревшим многими, и оно определенно "небезопасно", но оно использует его (мне нравится использовать его в обработчиках событий для приведения отправителя к нужному мне типу, но сначала все равно проверяет).
вам не нужно писать функцию, вы можете просто иметь эти две переменные, указывающие на одно место в некоторых точка.
вы можете использовать move для копирования необработанных байтов:
Assert(SizeOf(CardinalVar) = SizeOf(SingleVar);
Move(CardinalVar, SingleVar, SizeOf(CardinalVar));