Hi All,

I'm a long time Lazarus user (since Kylix failed) and a big fan. This is however my first post on any FPC/Lazarus forum.

The problem I've run into is a simple program (made in Lazarus) where I use floating point constants. It compiles and runs perfectly on Windows, but when cross-compiling for Linux, it fails for specific floating point values.

I realise immediately that, if this is a bug, it's probably an FPC bug and not Lazarus specific, but the problem is so obviously wrong, I'm thinking it cannot possibly be a compiler bug, and since I am cross-compiling from Lazarus, figured I would start asking here and rule out the obvious things first.

1. My Setup:
Fresh install of Lazarus IDE (SVN Revision 60307 - previous install also had the problem, so I updated) with FPC 3.04 installed on Windows 10 64bit (x86_64-win64) via fpcupdeluxe with compilers for Windows x86_64 and for Linux x86_64.  I run WSL Ubuntu 19.4 and also 18.4 in a VM and CentOS7 (because web), and a Linux Mint on my laptop, all of which get the same error. It compiles and runs perfectly correct in/for Windows.

2. Test case Program:

---------------------------------------------------

program fpbug;

// {$mode objfpc}{$H+}

uses
  Classes, SysUtils, Crt;

// {$R *.res}

var
  x: double;

begin
  // Successful Test:  (Win64 + Linux)
  WriteLn('');
  WriteLn('Setting Variable: x := 0.5; ');
  x := 0.5;
  WriteLn('FloatToStr( x )    --> ',FloatToStr(x));
  WriteLn('FloatToStr( 0.5 )  --> ',FloatToStr(0.5));

  // Failing Test:     (Win64 Pass,  Linux Fail (Ubuntu LTS)
  WriteLn('');
  WriteLn('Setting Variable: x := 0.35; ');
  x := 0.35;
  WriteLn('FloatToStr( x )    --> ',FloatToStr(x));
  WriteLn('FloatToStr( 0.35 ) --> ',FloatToStr(0.35));

end.
----------------------------------------------

I compile with standard debug options first, then production options (both Windows and Linux with CPU family x86_64 and target Processor Default)  and had an exhaustive run of enabling/disabling every compiler switch available in the standard Lazarus "Compilation and Linking" settings - all to no avail, the problem persists.

3. Windows console Output:

C:\Projects\[LAZARUS]\Temp\ConsoleAppTest>dir /w
 Volume in drive C has no label.
 Volume Serial Number is C234-0116

 Directory of C:\Projects\[LAZARUS]\Temp\ConsoleAppTest

[.]          [..]         [backup]     fpbug        fpbug.dbg fpbug.exe    fpbug.lpi    fpbug.lpr    fpbug.lps fpbug.res    fptest       fptest.dbg   fptest.exe   fptest.lpi fptest.lpr   fptest.lps   fptest.res   [lib]
rc           rc.exe       rc.lpi       rc.lpr       rc.lps
              19 File(s)      2 547 273 bytes
               4 Dir(s)  88 585 740 288 bytes free

C:\Projects\[LAZARUS]\Temp\ConsoleAppTest>fpbug

Setting Variable: x := 0.5;
FloatToStr( x )    --> 0.5
FloatToStr( 0.5 )  --> 0.5

Setting Variable: x := 0.35;
FloatToStr( x )    --> 0.35
FloatToStr( 0.35 ) --> 0.35

C:\Projects\[LAZARUS]\Temp\ConsoleAppTest>


4. Linux console Output:

cuzzy@CUZ-PC64:~/temp/ConsoleAppTest$ ls
backup  fpbug.dbg  fpbug.lpi  fpbug.lps  fptest fptest.exe  fptest.lpr  fptest.res  rc      rc.lpi  rc.lps fpbug   fpbug.exe  fpbug.lpr  fpbug.res  fptest.dbg fptest.lpi  fptest.lps  lib         rc.exe  rc.lpr
cuzzy@CUZ-PC64:~/temp/ConsoleAppTest$ ./fpbug

Setting Variable: x := 0.5;
FloatToStr( x )    --> 0.5
FloatToStr( 0.5 )  --> 0.5

Setting Variable: x := 0.35;
FloatToStr( x )    --> 0.35
FloatToStr( 0.35 ) --> Nan
cuzzy@CUZ-PC64:~/temp/ConsoleAppTest$


As the comments indicate, if I use the constant value 0.5 inside almost any function that takes a float (Double, Extended, Real, whatever), it works, both in Windows and Linux.

If I use the value 0.35 (or 0.66667 or 0.333333 - seemingly any number that has a non-exact round-trip IEEE754 representation, but this is merely a guess, no exhaustive testing) then in Windows on x86-64 it still works as expected, but on any Linux version, it returns NaN (as in my code example) or segfaults or such.

It is perfectly happy for me to assign the value to a variable and then use the variable (x in the example), but when I use the value directly, the skullduggery starts.

Tested functions (they all fail for a constant like 0.35): FloatToStr(), Trunc(), Round(), Ceil(), Floor()


Is there something I can check on my side? Does this work for others?  Might this be a cross-compile bug of sorts?  Is this some FPC, FPU or Linux peculiarity I'm not aware of?

Any help or insight would be appreciated - thanks,
Cuz



--
_______________________________________________
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus

Reply via email to