Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typecasting Cardinal to Single

Both Cardinal and Single are 4 byte / 32 bit datatypes, but when I typecast them to each other I get an Invalid Typecast error in Delphi 10.1 (Berlin).

lSingleVar := Single(lCardinalVar);

I am NOT talking about converting between the two types, as that will only store 23 bits of the cardinal data (the fraction part of the Single datatype). I need to store minimum 30 bits of data into a Single variable. I have good reasons for that (the type cannot be changed), which I will be pleased to elaborate on.

How do I typecast a Single variable?

like image 815
Hans Avatar asked May 08 '17 11:05

Hans


3 Answers

I would do it like this:

lSingleVar := PSingle(@lCardinalVar)^;

And in the opposite direction it would be:

lCardinalVar := PCardinal(@lSingleVar)^;

I cannot think of a more direct way to achieve what you request. To my mind this has the advantage of not requiring any type or function definitions.

like image 166
David Heffernan Avatar answered Nov 20 '22 06:11

David Heffernan


You can use a variant record to access the same underlying memory:

type
  TConverter = record
  case integer of
    0 : (c: cardinal);
    1 : (s: single);
  end;

And then use it like this:

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

  converter.c := lCardinalVar;
  lSingleVar := converter.s;

or with a single line typecast like this:

lSingleVar := TConverter(lCardinalVar).s

Variant parts in records

like image 34
Dalija Prasnikar Avatar answered Nov 20 '22 08:11

Dalija Prasnikar


You can write a function like this:

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

Here we use absolute keyword which means: variable value and AsSingle allocate the same memory. This keyword is considered obsolete by many, and it's definitely 'unsafe', but it has its uses (I like to use it in event handlers to cast Sender to the type I need, but first checking anyway).

You don't have to write a function, you can just have these two variables pointing to one place at some point.

like image 6
Yuriy Afanasenkov Avatar answered Nov 20 '22 07:11

Yuriy Afanasenkov