[offtopic] FreePascal

For other topics related to the FreeBASIC project or its community.
dodicat
Posts: 5984
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: [offtopic] FreePascal

Postby dodicat » Oct 24, 2018 21:53

Thanks for testing Roland.
freepascal doesn't have easy to use graphics (as far as I can see)
I have forgotten how to use wingraph.
And the graph unit seems tricky to use.

I have just tested the 32 bit graph code with a 64 bit dll and a 64 bit compiler.
Seems OK.
I notice that beep with 32 bits sounds different.
srvaldez
Posts: 2134
Joined: Sep 25, 2005 21:54

Re: [offtopic] FreePascal

Postby srvaldez » Oct 29, 2018 19:12

dodicat, if you are interested,here's the fpc-32-bit
let me know if or when you have downloaded so I can remove the link, if not, I will remove the link after one day
Last edited by srvaldez on Oct 30, 2018 3:15, edited 1 time in total.
srvaldez
Posts: 2134
Joined: Sep 25, 2005 21:54

Re: [offtopic] FreePascal

Postby srvaldez » Oct 29, 2018 21:08

Carlos Herrera wrote:Speed is one factor, another is accuracy. Please consider the following program

Code: Select all

(*-----------------------------------------------------------------------*)
(* EPSMACH computes the machine accuracy u (1.0+u>1.0,1.0+u/2=1.0)       *)
(*-----------------------------------------------------------------------*)
VAR II: INTEGER;
VAR ONE,TWO,U,EPSMACH: double;
BEGIN
   II:= 0;
   ONE:=1.0; TWO:=2.0; U:=1.0;
    REPEAT
      U:=U/TWO;
      II:=II+1;
    UNTIL ( (ONE+U)=ONE );
    EPSMACH := TWO*U;
    writeln (II, EPSMACH);
    readln;
END.

which is adopted from O. Montenbruck, T. Pfleger, Astronomy on the Personal Computer (Springer, 1998).

Free Pascal (3.0.4) results are:
53, 2.2204460...E-16.
Exactly the same results are obtained for FB64, however, FB32 (1.05.0) gives
64, 1.0842921..E-19.

So, apparently FB32 uses x87 instruction set, which is more accurate but slower...

if you want to use the FPU when compiling with FB x64 then pass the following flag on the compile command -Wc -mfpmath=387 ,for example
G:\FreeBASIC-1.06.0-win64\fbc -w all -asm intel -gen gcc -Wc -O2,-mfpmath=387 -v epsmach.bas
in my opinion the result of 64, 1.0842921..E-19 for double is wrong
Last edited by srvaldez on Oct 30, 2018 3:18, edited 1 time in total.
dodicat
Posts: 5984
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: [offtopic] FreePascal

Postby dodicat » Oct 30, 2018 0:43

Thanks srvaldez, I have downloaded the file.
marcov
Posts: 2792
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: [offtopic] FreePascal

Postby marcov » Oct 30, 2018 10:17

srvaldez wrote:in my opinion the result of 64, 1.0842921..E-19 for double is wrong


The result is never wrong. The code, and the whole principle of it is then wrong (and it has been wrong as long as the x87 CPU exists, quite a time), as it doesn't factor into the equation that a FPU might implement double with larger registers, and that inbetween results are not rounded to storage size (double in this case)

In C you could maybe solve it by making the variable volatile.
srvaldez
Posts: 2134
Joined: Sep 25, 2005 21:54

Re: [offtopic] FreePascal

Postby srvaldez » Oct 30, 2018 11:36

hello marcov, the code obviously is designed to give the bits of precision and epsilon of the type double which it doesn't when using the FPU, which suggest to me that the FPU precision flag is not set properly and therefore gives the wrong result
marcov
Posts: 2792
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: [offtopic] FreePascal

Postby marcov » Oct 30, 2018 11:58

srvaldez wrote:hello marcov, the code obviously is designed to give the bits of precision and epsilon of the type double


That was probably the intention, but the approach is incomplete and simply wrong if you are honest, and naive if you want to sugar coat it. At the very least the variable should be volatile, so that a read and write are always synchronized with the variable.

It looks something like a ported code fragment from some eighties compiler or interpreter that happened to work on those systems, because as ancient as they are, they didn't have any form of hardware floating point or optimization for floating point. Or from C but skipping the volatile modifier.

As usual, code that seems to work at first glance is not necessarily correct.

which it doesn't when using the FPU,


As I said in the original mail, IF you have some minimal optimization (like keeping results in registers), AND your floating point implementation uses larger registers than the variable type (also e.g. softfloat that often doesn't implement all sizes), this is the expected result. Also per IEEE standard afaik.

which suggest to me that the FPU precision flag is not set properly and therefore gives the wrong result


This has nothing to do with precision. If you enable FPU exceptions, you'd get an over/underflow on the conversion of the extended back to double, but the result doesn't change. But since everything are local variables that only live till the end of the procedure (or with optimization even less, last use), that store might even get eliminated, so that is no guarantee either.
marcov
Posts: 2792
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: [offtopic] FreePascal

Postby marcov » Oct 30, 2018 12:43

I checked with a compiler dev, and writes to volatile vars are not necessarily serialized with reads, so that makes the volatile suggestion uncertain too.
jj2007
Posts: 1259
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: [offtopic] FreePascal

Postby jj2007 » Oct 30, 2018 14:00

I made a quick test in assembler:

Code: Select all

    REPEAT
      U:=U/TWO;
      II:=II+1;
    UNTIL ( (ONE+U)=ONE );
    EPSMACH := TWO*U;
becomes

Code: Select all

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals II, double Two=2.0, U=1.0, REAL10 tmpvar, EpsMach
  Init
  .Repeat
   fld U
   fld Two
   fdiv
   fstp U   ; U:=U/TWO
   Print Str$("U=%Jf\n", U)
   inc II
   fld1      ; One
   fld U
   fadd ST, ST(1)
   fstp tmpvar
   Fcmp tmpvar, ST, top   ; comparing tmpvar with U+1, top precision
   fstp st
  .Until Zero?
  fld U
  fld st
  faddp
  fstp EpsMach
  Inkey Str$("E=%Jf\n", EpsMach)
EndOfCode

Output:

Code: Select all

U=0.5000000000000000000
U=0.2500000000000000000
U=0.1250000000000000000
U=0.06250000000000000000
U=0.03125000000000000000
...
U=1.734723475976807094e-18
U=8.673617379884035472e-19
U=4.336808689942017736e-19
U=2.168404344971008868e-19
U=1.084202172485504434e-19
E=2.168404344971008868e-19
What's the purpose the last value here? Equality is reached at 1.084e-19.
srvaldez
Posts: 2134
Joined: Sep 25, 2005 21:54

Re: [offtopic] FreePascal

Postby srvaldez » Oct 30, 2018 14:22

@marcov
you make good points, the code is ancient probably from before floating point hardware

@jj2007
the code is supposed to simulate a mantissa right-shift to determine the number of significant bits of the type double
marcov
Posts: 2792
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: [offtopic] FreePascal

Postby marcov » Oct 30, 2018 14:31

jj2007: if you don't print, you don't need to get the value of the stack. It remains in a x87 register. That is what causes the problem.

From what I see you forcedly pop and fld the value again, so that will probably work and give the low number. At least if you type it 8-byte instead of 10.
jj2007
Posts: 1259
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: [offtopic] FreePascal

Postby jj2007 » Oct 30, 2018 15:53

marcov wrote:jj2007: if you don't print, you don't need to get the value of the stack. It remains in a x87 register. That is what causes the problem.
No problem, tmpVar is REAL10. What I forgot is that top precision still leaves one LSB of tolerance; there is xtra precision, and that one produces exactly the same as FPC32.
srvaldez
Posts: 2134
Joined: Sep 25, 2005 21:54

Re: [offtopic] FreePascal

Postby srvaldez » Oct 30, 2018 19:36

@marcov
here's the point I was trying to make, this code works correctly
to compile with FB x64 do: fbc -w all -asm intel -gen gcc -Wc -O2,-mfpmath=387 epsmach.bas
to compile with FB x86 do: fbc -w all epsmach.bas
the result for both is: 53, 2.220446049250313e-016

Code: Select all

/'-----------------------------------------------------------------------'/
/' EPSMACH computes the machine accuracy u (1.0+u>1.0,1.0+u/2=1.0)       '/
/'-----------------------------------------------------------------------'/
dim as integer II
dim as double ONE,TWO,U,EPSMACH
dim as ushort oldcw, cw=&h27F

asm
   fstcw word ptr [oldcw]
   fldcw word ptr [cw] 'set FPU precision to double
end asm
II= 0
ONE=1.0 : TWO=2.0 : U=1.0
do
   U=U/TWO
   II=II+1
loop UNTIL ( (ONE+U)=ONE )
EPSMACH = TWO*U
asm
   fldcw word ptr [oldcw] 'restore control word
end asm
print II, EPSMACH
sleep

srvaldez
Posts: 2134
Joined: Sep 25, 2005 21:54

Re: [offtopic] FreePascal

Postby srvaldez » Nov 14, 2018 17:01

here's a nice introduction to Object Pascal http://newpascal.org/assets/modern_pasc ... ction.html

Return to “Community Discussion”

Who is online

Users browsing this forum: No registered users and 1 guest