[offtopic] FreePascal
Re: [offtopic] FreePascal
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.
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.
Re: [offtopic] FreePascal
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
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.
Re: [offtopic] FreePascal
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 exampleCarlos Herrera wrote: Speed is one factor, another is accuracy. Please consider the following programwhich is adopted from O. Montenbruck, T. Pfleger, Astronomy on the Personal Computer (Springer, 1998).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.
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...
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.
Re: [offtopic] FreePascal
Thanks srvaldez, I have downloaded the file.
Re: [offtopic] FreePascal
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)srvaldez wrote:in my opinion the result of 64, 1.0842921..E-19 for double is wrong
In C you could maybe solve it by making the variable volatile.
Re: [offtopic] FreePascal
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
Re: [offtopic] FreePascal
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.srvaldez wrote:hello marcov, the code obviously is designed to give the bits of precision and epsilon of the type double
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.
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 it doesn't when using the FPU,
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.which suggest to me that the FPU precision flag is not set properly and therefore gives the wrong result
Re: [offtopic] FreePascal
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.
Re: [offtopic] FreePascal
I made a quick test in assembler:becomes
Output:What's the purpose the last value here? Equality is reached at 1.084e-19.
Code: Select all
REPEAT
U:=U/TWO;
II:=II+1;
UNTIL ( (ONE+U)=ONE );
EPSMACH := TWO*U;
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
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
Re: [offtopic] FreePascal
@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
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
Re: [offtopic] FreePascal
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.
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.
Re: [offtopic] FreePascal
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.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.
Re: [offtopic] FreePascal
@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
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
Re: [offtopic] FreePascal
here's a nice introduction to Object Pascal http://newpascal.org/assets/modern_pasc ... ction.html