Title: Converting a floating point value to an integer value
Question: Delphi does not allow "casting" between integer and real data types. This shows how that can be achieved.
Answer:
Delphi has a rich selection of data types as shown below:
Pascal Data Types
=================
Integer Types
=============
Type Range Format
==== ===== ======
Integer -2147483648..2147483647 signed 32-bit
Cardinal 0..4294967295 unsigned 32-bit
Shortint -128..127 signed 8-bit
Smallint -32768..32767 signed 16-bit
Longint -2147483648..2147483647 signed 32-bit
Int64 -2^63..2^63 signed 64-bit
Byte 0..255 unsigned 8-bit
Word 0..65535 unsigned 16-bit
Longword 0..4294967295 unsigned 32-bit
Real Types
==========
Type Range
==== =====
Real48 2.9 x 10^-39 .. 1.7 x 10^38 48 bits
Single 1.5 x 10^-45 .. 3.4 x 10^38 32 bits
Double 5.0 x 10^-324 .. 1.7 x 10^308 64 bits
Extended 3.6 x 10^-4951 .. 1.1 x 10^4932 80 bits
Comp -2^63+1 .. 2^63 -1 1920 64 bits
Currency -922337203685477.5808.. 922337203685477.5807 64 bits
--------------------------------------------------------------------------
In Delphi it is possible to change the "type" of a variable by using the "cast" method.
For instance, you may have a character "tmpc" and an integer "tmpi", you cannot copy the contents of tmpi into tmpc as the compiler will complain. So, if you write;
--------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
tmpi: integer;
tmpc: char;
begin
tmpi:= 1;
tmpc:= tmpi;
end;
--------------------------------------------------------------------------
When this is compiled, you will will get the following compiler error:
[Error] Unit1.pas(66): Incompatible types: 'Char' and 'Integer'
However, if you use a "cast" to change the data type of "tmpi" as follows;
--------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
tmpi: integer;
tmpc: char;
begin
tmpi:= 1;
tmpc:= char(tmpi);
end;
--------------------------------------------------------------------------
This will compile correctly.
However, if you try to "cast" between integer and real data types you will find that the compiler will not let you. So if you have an integer data type "tmpi" and a real data type "tmpf and you compile the following code;
--------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
tmpi: integer;
tmpf: single;
begin
tmpf:= 1;
tmpi:= tmpf;
end;
-------------------------------------------------------------------------
you will get the following error;
[Error] Unit1.pas(66): Incompatible types: 'Integer' and 'Single'
This is because the data types are real and integer. So, you could try to "cast" between the two as follows;
-------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
tmpi: integer;
tmpf: single;
begin
tmpf:= 1;
tmpi:= integer(tmpf);
end;
-------------------------------------------------------------------------
Now you get the following compiler error;
[Error] Unit1.pas(66): Invalid typecast
Note that although they are both 32 bit data types but Delphi does not allow the type cast from a floating point numbers (real) to an integer numbers.
So, the way to do this is to use a pointer to "point" to the real number memory location and then to "read" the value of that loaction into an integer variable.
The following function performs this task:
{-----------------------------------------------------------------------------
Function: TMainForm.FloatToLongword
Author: Jim Carter - Xtronix Ltd - www.xtronix.co.uk
Date: 24-Mar-2003
Arguments: Value: single (floating point number 32 bits)
Result: Longword - The float data is copied into a Longword (32 bits)
Notes: This is required as Delphi does not allow a cast between floating
and integer numbers
-----------------------------------------------------------------------------}
function FloatToLongword(val: single): longword;
var
p: ^longword; //assign pointer that is referenced to longwords
begin
p:=@(val); //point to user floating point data address (32 bits)
result:=p^; //copy the float data to the longword result(32 bits)
end;
============================================================================
Jim Carter - Xtronix Ltd