Recent

Author Topic: Different results with Lazarus and Delphi  (Read 3691 times)

Ian

  • New member
  • *
  • Posts: 7
Different results with Lazarus and Delphi
« on: October 21, 2017, 05:04:38 am »
Hello,

I've developed a simulation model that compiles in both Delphi and Lazarus.  The Lazarus version is a console application.  When I run the Lazarus program on either Windows or Linux, it gives identical results.  However, when I run the same model from a GUI developed in Delphi, it gives different results.  The model is iterative, doing many sequential calculations where each set of calculations depends on the results from round of calculations.  It's possible that it is due to the compounding effect of very small differences in the results generated by the different compilers.  Of course, I may have some sort of mistake(s) in my code...

Note that both programs are double precision.  I did see some differences between 32 and 64 bit in Delphi, but both the Lazarus and Delphi programs are 64 bit.

I'd be interested to hear if anyone has encountered this sort of thing before, or has any suggestions as to what is going on.  I realize I'm a bit light on detail here - happy to elaborate if necessary.

Thanks, Ian

Handoko

  • Hero Member
  • *****
  • Posts: 5122
  • My goal: build my own game engine using Lazarus
Re: Different results with Lazarus and Delphi
« Reply #1 on: October 21, 2017, 05:28:20 am »
Hello Ian,
Welcome to the forum.

Lazarus' LCL does not share the same code with Delphi's VCL, so there will have some incompatibility issues. You can read more here:
http://wiki.freepascal.org/Lazarus_For_Delphi_Users#VCL_-.3E_LCL

If you don't mind, you can show us the code here. If for some reasons you're not willing to make the code public, you can create a simple compilable demo that showing the issue. Copy all the necessary files to a new folder, compress the folder and send the zip file to the forum. Please provide enough information, like: OS, widgetset, Lazarus version, etc. And it will better if you can provide some screenshots.

Ian

  • New member
  • *
  • Posts: 7
Re: Different results with Lazarus and Delphi
« Reply #2 on: October 21, 2017, 05:48:41 am »
Hello Handoko,

Thanks for the quick reply.  It's tricky for me to provide code as it is a complex model with many files and so on.  I appreciate that the next step may be for me to generate some code that does the same sort of thing. 

First though, my program is not using any visual components.  The mathematical model is in a completely separate project (.bpl in Delphi) that both Lazarus and the Delphi IDE can see.  Lazarus sends information to this program via a .json input file.  For comparison, and for my own convenience so that I don't have to do all analysis from a console application, I wrote a simple windows interface that reads the .json file and runs the model through identical code, that is, things like this:

  err_sim := Model.RunConsole;

The model involves solving a soil water balance that divides the day into 1 hour or less (depending on various factors) time increments, and then runs for a couple of years.  Since movement of water can be quite slow, many of the values generated vary only slightly from one iteration to another. 

I'm just wondering if continually taking differences of numbers that vary very slightly can result in a degree of numerical instability - the famous Butterfly Effect highlighted by Lorenz.

Perhaps I just have to do more digging!

Ian

Ian

  • New member
  • *
  • Posts: 7
Re: Different results with Lazarus and Delphi
« Reply #3 on: October 21, 2017, 07:02:22 am »
Hello again Handoko,

Well, I've answered my own question - as is generally the case, I was doing something wrong!

It turns out that I'd not fully converted all my Delphi files to 64 bit, whereas Lazarus is 64 bit.  When I fixed that up, everything fell into place...

Anyway, thanks for looking at it for me, and it's good to know this forum is here.

Best regards, Ian

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Different results with Lazarus and Delphi
« Reply #4 on: October 21, 2017, 12:20:47 pm »
Do you use the type Extended in your Delphi calculations?
Andalso in the fpc part (Lazarus is just the GUI stuff basically)?

In 64-bit the type extended maps to type double, so this may explain the different results in Delphi and fpc.
If you need the extended precision, you should compile for 32-bit (or use another (custom) type with better precision).

Bart

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 844
Re: Different results with Lazarus and Delphi
« Reply #5 on: October 21, 2017, 12:49:18 pm »
Make sure, FPU/SSE flags are the same. Set precision manually via SetPrecisionMode.
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

Ian

  • New member
  • *
  • Posts: 7
Re: Different results with Lazarus and Delphi
« Reply #6 on: October 23, 2017, 12:12:07 am »
Thanks Bart and Mr. Madguy...

I'm now getting the same results with fpc and Delphi in 64 bit, so I can see that the problem was probably with how I was setting double precision in Delphi.  I'm going to stick with 64 bit so it should all be fine. 

I will check out your suggestions so I've got a better understanding of how the types are working.

Best regards,

Ian

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 844
Re: Different results with Lazarus and Delphi
« Reply #7 on: October 23, 2017, 09:49:31 am »
My own project, that uses FFT, has this lines in it's initialization code:
Code: [Select]
  TFourierForm = class(TForm)
  private
    { private declarations }
  public
    { public declarations }
    Mask:TFPUExceptionMask;
    Precision:TFPUPrecisionMode;
  end; 

procedure TFourierForm.FormCreate(Sender: TObject);
begin
  Mask := Math.SetExceptionMask(MaskAllExceptions);
  Precision := Math.SetPrecisionMode(pmExtended);
end; 

procedure TFourierForm.FormDestroy(Sender: TObject);
begin
  Math.SetExceptionMask(Mask);
  Math.SetPrecisionMode(Precision);
end;     
Both 32bit and 64bit show the same results. As I know, 32bit programs use FPU, while 64bit ones use SSE. This two should be 100% compatible, but default flags may be different. For example: while having internal 80bit registers, FPU may have single precision by default. You should change it manually. Also, if you use rounding - make sure round modes are also the same via SetRoundMode.
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

 

TinyPortal © 2005-2018