将红衣主教打字为单身

Typecasting Cardinal to Single

CardinalSingle 都是 4 字节/32 位数据类型,但是当我将它们相互转换时,我在 Delphi 10.1 中收到 Invalid Typecast 错误(柏林).

lSingleVar := Single(lCardinalVar);

我不是在谈论在两种类型之间转换,因为这只会存储 23 位的基数数据(Single datatype 的小数部分)。我需要将至少 30 位数据存储到 Single 变量中。我有充分的理由(类型不能更改),我很乐意详细说明。

如何对 Single 变量进行类型转换?

您可以使用变体记录来访问相同的底层内存:

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;

或者像这样使用单行类型转换:

lSingleVar := TConverter(lCardinalVar).s

Variant parts in records

我会这样做:

lSingleVar := PSingle(@lCardinalVar)^;

反之则为:

lCardinalVar := PCardinal(@lSingleVar)^;

我想不出更直接的方法来实现您的要求。在我看来,这具有不需要任何类型或函数定义的优点。

你可以这样写一个函数:

function ConvertCardinalToSingle(value: Cardinal): Single;
var AsSingle: Single absolute value;
begin
  Result := AsSingle;
end;

这里我们使用absolute关键字,意思是:变量valueAsSingle分配相同的内存。这个关键字被很多人认为是过时的,它肯定是 'unsafe',但它有它的用途(我喜欢在事件处理程序中使用它来将 Sender 转换为我需要的类型,但无论如何都要先检查)。

你不必写一个函数,你可以让这两个变量在某个时候指向一个地方。

您可以使用 move 来复制原始字节:

Assert(SizeOf(CardinalVar) = SizeOf(SingleVar);
Move(CardinalVar, SingleVar, SizeOf(CardinalVar));