Home > Software design >  Why is this code causing an 'Invalid Floating Point Operation' error?
Why is this code causing an 'Invalid Floating Point Operation' error?

Time:07-26

When executing the below code, it should calculate the distance to the horizon using the current height, but it is able to calculate only up to 63 meters high, then an 'Invalid Floating Point Operation' from 64 meters onwards.

Why is this error occurring?

unit Unit_ch4_2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  r:real;
begin
  r := SQRT(SQR(6350000   StrToint(Edit1.Text)) - SQR(6350000));
  Edit2.Text := FloatToStr(r / 1000);
end;

end.

CodePudding user response:

The data types used in your code are too small to hold bigger intermediate values respectively Delphi assumes wrong about what intermediate data types to use here by your calls to SQR and StrToInt!

When you explicitly tell the compiler to use a bigger data type like Int64 by defining a constant of that type and by using StrToInt64 the code now runs without errors with entered values up to 99 999 999 999!

procedure TForm1.Button1Click(Sender: TObject);
const
  v: int64 = 6350000;
var
  r: real;
  a: int64;
begin
  Edit2.Clear;
  a := SQR(v   StrToInt64(Edit1.Text)); // this line can give a negative result when the parameter passed to SQR is too big
  r := SQRT(a - SQR(v)); // negative parameter of SQRT causes an error!
  Edit2.Text := FloatToStr(r / 1000);
end;

In the code above I used an extra line for storing an intermedia value in an extra local variable, to show which part of the calculation exactly caused the error. If the parameter of SQR is too big (even when Int64 is used), the result in a is a negative number. This then leads to an error when calling SQRT!

Below is a code version in the same short format as you used:

procedure TForm1.Button1Click(Sender: TObject);
const
  v: int64 = 6350000;
var
  r: real;
begin
  Edit2.Clear;
  r := SQRT(SQR(v   StrToInt64(Edit1.Text)) - SQR(v));
  Edit2.Text := FloatToStr(r / 1000);
end;
  • Related