Typecasting Cardinal单身

Han*_*ans 9 delphi delphi-10.1-berlin

两个CardinalSingle是4字节/ 32比特的数据类型,但是当我他们类型强制转换为彼此我得到一个Invalid Typecast错误的Delphi 10.1(柏林).

lSingleVar := Single(lCardinalVar);
Run Code Online (Sandbox Code Playgroud)

我不是在谈论在两种类型之间进行转换,因为它只存储23位基数数据(Single数据类型的小数部分).我需要将至少30位数据存储到Single变量中.我有充分的理由(类型无法更改),我将很乐意详述.

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

Dav*_*nan 11

我会这样做:

lSingleVar := PSingle(@lCardinalVar)^;
Run Code Online (Sandbox Code Playgroud)

而在相反的方向,它将是:

lCardinalVar := PCardinal(@lSingleVar)^;
Run Code Online (Sandbox Code Playgroud)

我想不出更直接的方式来实现你的要求.在我看来,这具有不需要任何类型或功能定义的优点.


Dal*_*kar 9

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

type
  TConverter = record
  case integer of
    0 : (c: cardinal);
    1 : (s: single);
  end;
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

var
  converter: TConverter;
  lCardinalVar: cardinal;
  lSingleVar: single;

  converter.c := lCardinalVar;
  lSingleVar := converter.s;
Run Code Online (Sandbox Code Playgroud)

或者像这样的单行类型:

lSingleVar := TConverter(lCardinalVar).s
Run Code Online (Sandbox Code Playgroud)

记录中的变体部分

  • 您可以通过编写`lSingleVar:= TConverter(lCardinalVar).s;`来避免局部变量,编译器将发出一个简单的mov操作,就像它在我的答案中为代码发出的一样 (2认同)

Yur*_*kov 6

你可以写一个这样的函数:

function ConvertCardinalToSingle(value: Cardinal): Single;
var AsSingle: Single absolute value;
begin
  Result := AsSingle;
end;
Run Code Online (Sandbox Code Playgroud)

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

您不必编写函数,只需将这两个变量指向某个位置即可.