Re: [fpc-pascal] PTCGraph resolution detection

2024-03-22 Thread James Richters via fpc-pascal
I found another way to get the screen resolution in Windows that is
consistent between 32bit and 64bit programs using GetSystemMetrics.

uses
  Windows;

var
  ScreenWidth, ScreenHeight: Integer;

begin
  ScreenWidth := GetSystemMetrics(SM_CXSCREEN);
  ScreenHeight := GetSystemMetrics(SM_CYSCREEN);

  WriteLn('Screen Width: ', ScreenWidth, ' pixels');
  WriteLn('Screen Height: ', ScreenHeight, ' pixels');
end.

This works well, and with PTCGraph, there is really no need to bother
figuring out what video modes are available anyway, especially now that we
can have custom resolutions for the PTCGraph window, I just need to make
sure it fits on the screen so it really doesn't matter how I get the screen
resolution.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] PTCGraph resolution detection

2024-03-20 Thread James Richters via fpc-pascal
>>No idea, but it does sound like a Windows issue to me. 
>>Or a video card driver issue? 
>>The API is the same. The mechanism for obtaining the list of resolutions is 
>>also the same. 
>>Perhaps Microsoft uses a fake DirectDraw shim in 64-bit Windows that presents 
>>a fake resolutions list, because they can? 
>>Perhaps it is an issue, related to the video card drivers? 
>>What are the video cards on the two machines that you have tested?

I added the following line in the while m loop
Write(m^.MaxX+1, 'x', m^.MaxY+1,' Mode ',m^.ModeNumber,'-', m^.MaxColor,'Colors 
');
and with 64 bit on just the one machine with the 1080x2560 monitor, it lists 
all modes, including 1080x2560 and goes all the way to 2160x3840... but it is 
correctly only showing portrait resolutions.
On the 1280x1024 PC with the 64bit version, it goes up to all the modes that 
have 1280x1024 and stops, because the monitor cannot display more than that. 

when I compile it as Win32 it stops at the monitor resolution on both computers.

The computers are identical: Intel i3-4170 with motherboard intel graphics, no 
separate video card.  They both have Windows 10 Pro.

I just stuck my own variables in there were I can just tell it the resolution 
of the monitor, and if I put in 0x0 it does the original autodetect thing.  
With me supplying the monitor resolution, everything is now working correctly.

James




___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] PTCGraph resolution detection

2024-03-19 Thread James Richters via fpc-pascal
I am trying to compile a program that uses PTCGraph for Windows 64 bit, and
it's not behaving the same as it does on Win32.
When I compile it for Win32, it is correctly detecting my monitor resolution
I have a vertical monitor with a resolution of 1080x2560  
 
When I run the Win32 program I correctly get:
Max resolution:1080x2560 
 
The 64bit version incorrectly produces:
Max resolution:2160x3840 
 
I tried it on another computer with a 1280x1024 monitor and it correctly
identifies it on both versions.
 
Below is the procedure that gets the monitor resolution.
 
I am using the current trunk of FPC installed today. 
 
Does anyone have any idea why the 64bit version would work differently than
the 32bit version?
 
James
 
 
 
Uses
   Windows,ptcgraph,ptccrt,crt,sysutils;
 
 
Procedure WindowsGRAPHINIT;
 
Var
gd,gm:smallint;
m: PModeInfo;
graphinitialize,MaxX,MaxY:Integer;
Begin
   Windowtitle:='ptcgraph';
   graphinitialize:=1234;
   MaxX:=0;
   MaxY:=0;
   m := QueryAdapterInfo;
   while m <> nil do
  begin
 If m^.MaxX+1>MaxX then
MaxX:=m^.MaxX+1;
 If m^.MaxY+1>MaxY then
 MaxY:=m^.MaxY+1;
 m := m^.next;
  end;
   Writeln ('Max resolution:',MaxX,'x',MaxY);
   gd:=VESA;
 
gm:=InstallUserMode(WindowXResolution,WindowYResolution,65536,1,1,1)
;
   If gm<0 Then
  Begin
 Writeln('Error Installing Graphics ',gm,' ',grapherrormsg(gm));
 Halt(70);
  End;
   PtcGraph.InitGraph(gd,gm,'');
. snip .
 
 
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-22 Thread James Richters via fpc-pascal
I seem to recall there is some way to get 80 Bit Extended on 64 Bit Windows, 
but it involved compiling a 64bit version of FPC myself somehow, and I can't 
remember what it was all about, I'm pretty sure I was doing that for a while, 
but then I wanted to upgrade and couldn't remember how it was all done, so I 
went back to Win32, just to get 80 Bit Extended.   It's something to do with 
the cross compiler to 64 bit makes extended a double on 64bit, but if you 
weren't cross compiling and had just a native 64bit compiler then Extended is 
80 bits again.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-20 Thread James Richters via fpc-pascal
ELN ( '  Const_Ans2 = ', Const_Ans2);
   WRITELN ( 'Var_Ans2 = ', Var_Ans2);
   WRITELN ( ' Difference2 = ', Difference2);
   Writeln;
   WRITELN ( '  Const_Ans3 = ', Const_Ans3);
   WRITELN ( 'Var_Ans3 = ', Var_Ans3);
   WRITELN ( ' Difference3 = ', Difference3);

End.

  Const_Ans1 =  2.85714298486709594727E-0001
Var_Ans1 =  2.85714285714285714282E-0001
 Difference1 = -1.27724238804447203649E-0008

  Const_Ans2 =  1.42857142857142857141E-0001
Var_Ans2 =  1.42857142857142857141E-0001
 Difference2 =  0.E+

  Const_Ans3 =  8.97597901025655211019E-0001
Var_Ans3 =  8.97597901025655211019E-0001
 Difference3 =  0.E+


If division by a single forced the answer to be a single, thenConst_Ans3
:= Pi/B_Const; produce a single
But it does not, it correctly produces extended results with both Variables
and Constants.

Const_Ans1  := A_Const/B_Const; is incorrectly being evaluated as a single
and I don't know why.
The fact that there is something in Difference1 but not Difference2 or
Difference3 is why I think there is a bug somewhere.
I am expecting my byte divided by a single to be an extended for both
variables and constants, but only variables is working.

Surely if a Byte divided by a byte can result in an extended than a Byte
divided by a single should also result in an extended.

It's like this for everything,  you can add a byte to a byte and get a word
for an answer, 
the result of any math can always result in higher precision than all of the
terms involved, 
otherwise there would be no point to double precision or extended precision.
I have never needed to cast my terms to get expected results.
Are we really supposed to do:

MyConstant = Extended(2.5)/Extended(3.5);   to get it to be an extended?

MyConstant = 2.5/3.5 should result in an extended, I shouldn't need the
casting. 

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-19 Thread James Richters via fpc-pascal
>I would not put too much trust in Windows calculator, since there you have
no control over the precision at all.
The actual CORRECT answer according to
https://www.wolframalpha.com/input?i=1%2F3.5 Is 
0.285714 Repeating forever

Which is what I get on windows only when using Variables.
   Var_Ans1 =  2.85714285714285714282E-0001
Which as you can see the .285714 repeats exactly 3 times with two more
correct digits, for a total of 20 correct digits before we run out of
precision. 

>It seems to be a windows-specific problem. Here is the result of your
program when executed on Linux:
>  Const_Ans1 =  2.85714298486709594727E-0001
>Var_Ans1 =  2.85714298486709594727E-0001

>As you can see, the result is identical.
Great, Linux is consistently giving you the wrong answer, and I notice it's
the same wrong I answer I get when I use constants.

I don't know why it would be different in Windows than on Linux. 
I am curious what you get in Linux for:
A_const = (2/7);   // should be 0.285714 Repeating forever also
Or 
B_const = (2/7)-(1/3.5);  //should always be 0;

Just for fun I ran it on Turbo Pascal 7.0 for DOS and got:
 Const_Ans1 =  2.85714285714286E-0001
 Var_Ans1 =  2.85714285714286E-0001

I also noticed that re-casting constants is not allowed by Turbo Pascal 7.0,
so I removed the unnecessary re-casting so it would compile, but I did get
the expected answer even without re-casting it... as I expected I should. 
The fact that Turbo Pascal gives be the correct answer to 14 digits even
though in Turbo Pascal I also divided a byte by a single shows that I should
expect my pascal programs to provide THIS correct answer, 0.285714 repeating
until you run out of precision,  not something else. And it shows that a
byte divided by a single is in fact able to be an extended... it also proves
that in Pascal the result of a byte divided by a single is NOT limited to
single precision. 

2.85714298486709594727E-0001 makes no sense to me at all, It's like it did
the calculation in Single precision, then stored it in an extended, but if I
wanted to work in single precision, I would not have set my variable to
extended.

There is some flawed logic somewhere that says if you do math with a single,
the result is a single, but this is simply not correct, you can divide a
byte by a byte and get an extended, and you can divide a single by a single
and get an extended, Pascal has ALWAYS worked that way.
Forcing the result of an equation to be a single because one term is a
single is just not right. 

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-19 Thread James Richters via fpc-pascal
>And if you have set the precision, then the calculation will be identical to 
>the calculation when you use a variable of the same type (if not, it's indeed 
>a bug).
 
This is what I have been trying to point out.  Math with identical casting with 
variables and constants are not the same.
Maybe if I try with a simpler example:
 
program Const_Vs_Var;
 
Const
   A_const = Byte(1);
   B_const = Single(3.5);
Var
   A_Var : Byte;
   B_Var : Single;
   Const_Ans1, Var_Ans1 : Extended;
 
Begin
   A_Var := A_Const;
   B_Var := B_Const;
 
   Const_Ans1 := Extended(Byte(A_Const)/Single(B_Const));
   Var_Ans1   := Extended(Byte(A_Var)/Single(B_Var));
 
   WRITELN ( ' Const_Ans1 = ', Const_Ans1);
   WRITELN ( '   Var_Ans1 = ',   Var_Ans1);
End.
 
Const_Ans1 =  2.85714298486709594727E-0001
   Var_Ans1 =  2.85714285714285714282E-0001
 
Windows 10 Calculator shows the answer to be
0.28571428571428571428571428571429  Which matches up with the way variables 
have done this math, not the way constants have done it.
 
I am explicitly casting everything I possibly can.
 
Without the :20:20 you can see that the result of each of these is in fact 
extended, but they are VERY different numbers, even though my casting is 
IDENTICAL , and I can’t make it any more the same, the results are very 
different.  Math with Variables allows the result of a low precision entity, in 
this case a Byte, divided by a low precision entity, in this case a Single, to 
be calculated and stored in an Extended, Math with Constants does not allow 
this possibility, and this is where all the confusion is coming from.Two 
identical pieces of code not producing the same results.
 
Math with Constants is NOT the same as Math with Variables, and if this one 
thing was fixed, then all the other problems go away.
I am doing:  
   Const_Ans1 := Extended(Byte(A_Const)/Single(B_Const));
   Var_Ans1   := Extended(Byte(A_Var)/Single(B_Var));
 
Just to make a point, but the code:
 
   Const_Ans1 := A_Const/B_Const;
   Var_Ans1   := A_Var/B_Var;
 
Should also produce identical results without re-casting, because A_Const  and 
A_Var are both defined to be a Byte, and B_Const and B_Var are both defined to 
be a Single, and Const_Ans1 and Var_Ans1 are both defined to be Extended. 
 
Why are the result different?  
 
As I tried to explain before, if I force all constants to be Extended:
Const_Ans1 := Extended(Extended(A_Const)/Extended(B_Const));
 
Then I do get the correct results, but this should not be needed, and this 
casting is wrong,  because a byte divided by a single should be able to be 
extended without first storing them in extended entities, the same as it is 
with variables. 
 
With variables I do not need to re-cast every single term in an expression as 
Extended to get an Extended answer. 
With constants this is the ONLY way I can get an extended answer. 
 
Before the changes to 2.2, all constants WERE at highest precision, so the math 
involving constants never had to bother with considering that a low precision 
number divided by a low precision number could end up as an extended, because 
there were no low precision constants at all.But now there are, and that’s 
really fine, because we often have low precision variables, and that’s fine, 
but the math needs to be done the same way whether with constants or variables 
to produce identical results so now math with constants also has to take into 
consideration that math with low precision entities can and often does result 
in a high precision answer. 
 
To demonstrate that a low precision entity divided by a low precision entity 
should always be able to be an Extended, use this example my constants as BYTES 
so there can be no lower precision:
 
program Const_Vs_Var;
 
Const
   A_const = Byte(2);
   B_const = Byte(7);
Var
   A_Var : Byte;
   B_Var : Byte;
   Const_Ans1, Const_Ans2, Var_Ans1 : Extended;
 
Begin
   A_Var := Byte(A_Const);
   B_Var := Byte(B_Const);
 
   Const_Ans1 := A_Const/B_Const;
   Var_Ans1   := A_Var/B_Var;
 
   WRITELN ( ' Const_Ans1 = ', Const_Ans1);
   WRITELN ( '   Var_Ans1 = ',   Var_Ans1);
End.
 
Const_Ans1 =  2.85714285714285714282E-0001
   Var_Ans1 =  2.85714285714285714282E-0001
 
Now as you can see math with constants is EXCATLY the same as math with 
variables again, and I did not need to do any ridiculous casting to get the 
correct answer. 
 
I hope this makes sense.  I know exactly what is happening, but I don’t know 
why and I don’t know how to explain it other than to give these examples.
 
1/3.5 == 2/7
 
What should this program produce?
 
program Const_Vs_Var;
 
Const
   A_const = (2/7)-(1/3.5);
Begin
   WRITELN ( ' A_Const = ', A_Const);
End.
 
 
How can this possibly be right?
A_Const = -1.27724238804447203649E-0008
 
 
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-16 Thread James Richters via fpc-pascal
>But the reduced precision should not come unexpectedly simply because the
compiler attaches type attributes to constants (which can't be easily 
>explained), and then the outcome of simple decimal arithmetic is incorrect.

How are you disagreeing? This is EXACTLY what I am saying. My math with
variables is ALWAYS correct, my math with Constants is not coming out the
same and can't be easily explained.  I guess I should have re-posted the
example because it's not as it seems,  this is a counterexample I had
provided to show the  incorrect math indeed could force an INCREASE in
Precision, but even if I don't cast the variables you still get the same
unexpected results.. this is just to demonstrate that the problem is not the
reduction and assignment itself, but it's the way calculations are done by
the compiler being wrong. 

The math with constants is what's wrong, not the reduction in precision.
Look closely at the following example.  I am ALWAYS adding an integer to a
byte divided by a Single... The reduction in precision has been removed from
this example because I explicitly cast what I wanted.

This proves that the math with constants is what the problem is, not that
the constants themselves were reduced in precision.

The results of Const_Ans1 MUST Equal Var_Ans1 EXACTLY or all kinds of
problems will arise. 

I have no reason to expect that the results of Var_Ans1 and Const_Ans1 would
be different, yet they are.   THIS is the Problem, and that's pretty much
exactly what you just said, so I believe we are in agreement.

The problem isn't that the reduction in precision assigned a type attribute
to the constant, it's that the math with that type is being done wrong,
because I can do the math with the EXACT same typed variables and it comes
out correctly.  I'm trying to show where the real problem is, (not very
successfully)

Math with Variables in the executing program, a byte / single can very well
be extended. 
With the compiler math a byte / single is FORCED to be a single, which is
incorrect.
Dividing by a single does NOT imply the result should be a single.

Before the changes in v2.2, this was NEVER an issue, because all the
constants were full precision, so this could never possible come up as there
would be no math with a single in it.

My point is, no matter what is wrong, the result of math with constants must
always be exactly the same as math with variables otherwise no one can
figure out what the heck is going on. 

James


program Const_Vs_Var;

Const
   A_const = Integer(8427);
   B_const = Byte(33);
   C_const = Single(1440.5);
   Win_Calc = 16854.045817424505380076362374176;
   Const_Ans = 16854.045817424505380076362374176 / (8427 + 33 / 1440.5); Var
   A_Var : Integer;
   B_Var : Byte;
   C_Var : Single;
   Const_Ans1, Var_Ans1 : Extended;

Begin
   A_Var := A_Const;
   B_Var := B_Const;
   C_Var := C_Const;

   Var_Ans1   := Win_Calc / (A_Var+B_Var/C_Var);
   Const_Ans1 := Win_Calc / (A_Const+B_Const/C_Const);

   WRITELN ( '  Const_Ans = ',  Const_Ans:20:20);
   WRITELN ( ' Const_Ans1 = ', Const_Ans1:20:20);
   WRITELN ( '   Var_Ans1 = ',   Var_Ans1:20:20);
End.

The result is:
  Const_Ans = 2.0010627116630224
 Const_Ans1 = 2.0010627116630224
   Var_Ans1 = 2.


When I do:
   Var_Ans1   := Win_Calc / (A_Var+B_Var/C_Var);
   Const_Ans1 := Win_Calc / (A_Const+B_Const/C_Const);





-Original Message-
From: fpc-pascal  On Behalf Of
Bernd Oppolzer via fpc-pascal
Sent: Friday, February 16, 2024 10:48 AM
To: James Richters via fpc-pascal 
Cc: Bernd Oppolzer 
Subject: Re: [fpc-pascal] Floating point question


Am 16.02.2024 um 15:57 schrieb James Richters via fpc-pascal:
>> So you are saying when constant propagation is on, an expression should
have a different result than with constant propagation off?
> The result of math when using constants MUST be the same as the result of
identical math using variables.
>
> There should never be a difference if I did my formula with hard coded
constants vs variables.
>
>Const_Ans = 2.0010627116630224
>   Const_Ans1 = 2.0010627116630224
> Var_Ans1 = 2.
>
> This should not be happening.
>
> James

See my other post;

if the developer explicitly wants reduced precision, then this is what
happens.
But the reduced precision should not come unexpectedly simply because the
compiler attaches type attributes to constants (which can't be easily
explained), and then the outcome of simple decimal arithmetic is incorrect.

So I have to disagree, sorry.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-16 Thread James Richters via fpc-pascal
>So you are saying when constant propagation is on, an expression should have a 
>different result than with constant propagation off?

The result of math when using constants MUST be the same as the result of 
identical math using variables.

There should never be a difference if I did my formula with hard coded 
constants vs variables.

  Const_Ans = 2.0010627116630224
 Const_Ans1 = 2.0010627116630224
   Var_Ans1 = 2.

This should not be happening.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-13 Thread James Richters via fpc-pascal
Ok, maybe this example will prove why it's not happening correctly:

program Const_Vs_Var;

Const
   A_const = Integer(8427);
   B_const = Byte(33);
   C_const = Single(1440.5);
   Win_Calc = 16854.045817424505380076362374176;
   Const_Ans = 16854.045817424505380076362374176 / (8427 + 33 / 1440.5);
Var
   A_Var : Integer;
   B_Var : Byte;
   C_Var : Single;
   Const_Ans1, Var_Ans1 : Extended;

Begin
   A_Var := A_Const;
   B_Var := B_Const;
   C_Var := C_Const;

   Var_Ans1   := Win_Calc / (A_Var+B_Var/C_Var);
   Const_Ans1 := Win_Calc / (A_Const+B_Const/C_Const);

   WRITELN ( '  Const_Ans = ',  Const_Ans:20:20);
   WRITELN ( ' Const_Ans1 = ', Const_Ans1:20:20);
   WRITELN ( '   Var_Ans1 = ',   Var_Ans1:20:20);
End.

The result is:
  Const_Ans = 2.0010627116630224
 Const_Ans1 = 2.0010627116630224
   Var_Ans1 = 2.



Now you can see, if the math was done the same as the way math is done for
variables, we could have stored the constants as Byte(2).   But because the
math is being carried out after the reduction in precision we are left with
storing this as extended. 

If the result of all the math can be reduced, or if there is no math, then
it's great to reduce precision, but if the reduction in precision happens
before the math, you can end up with the opposite of what you intended.
Sure the compiler is working with faster math, but who cares what the
compiler has to do, now we're going to be stuck with a program using
extended(2.0010627116630224) for any calculations that use Const_Ans
instead of byte(2);  if Const_Ans is used in some kind of iterative process,
it the program could be using this extended millions of times when it could
have been using a byte.

Notice when I do the EXACT same math with variables, it DOES give me a
result of 2, and THAT can be reduced.

If the answer after all the math can be reduced, it should be reduced, if it
can't be, then it should not be.

Math with constants should be the same as math with variables.

I'm trying to show there doesn't need to be a trade off at all, the math
with constants just needs to be done correctly... as in the exact same way
math with variables is done.

What has happened is the math with constants was written and tested with the
assumption that all constants would be full precision, because it was
impossible for constants to be anything other than full precision, but now
that is no longer the case and the math with constants isn't working
correctly anymore.  Either the math needs to happen before the reduction in
precision or the math needs to be fixed so it works the same as math with
variables, either way there won't need to be a trade off and everything will
work the way everyone wants it to.. performance when possible and precision
when needed.

James



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-13 Thread James Richters via fpc-pascal
>As Jonas said, this would result in less efficient code, since all the math
will then be done at full precision, which is slower.
I don't think I'm explaining it well,  I'm saying where there is an entire
formula that the compiler needs to evaluate, what's happening now, is that
each term is being reduced in precision first, Then the math happens, and
the result it stored.  
If instead the compiler did all the math first, THEN ran the function that
determines if the entire answer should be reduced in precision, then the
math would work correctly. 

But we don't care how long it takes to do the math during the compile, the
constants are only compiled once and stored in the executable.   The reason
to do all this is to make the executing program that ends up using the
constants over and over many times more efficient, the speed of the
compilation is irrelevant.

>As usual, it is a trade-off between size (=precision) and speed.
I agree with that, but only in the executing program, not the compiler.  

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-13 Thread James Richters via fpc-pascal
Sorry for the kind of duplicate post, I submitted it yesterday morning and I
thought it failed, so I re-did it and tried again.. then after that the
original one showed up.  
 
A thought occurred to me.   Since the complier math is expecting all the
constants would be in full precision, then the compiler math doesn't need to
change, it's just that the reduction in precision is just happening too
soon.  It's evaluating and reducing each term of an expression, then the
math is happening, and the answer is not coming out right.
 
If instead everything was left full precision until after the compiler math
(because this is what the compiler math expects), and then the final answer
was reduced in precision where possible, then it would work flawlessly.  So
the reduction in precision function only needs to run once on the final
answer, not on every term before the calculation. 
 
Sorry again for the duplicate.   
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-13 Thread James Richters via fpc-pascal
 in high precision and
portions that are highest performance possible, then what is the correct way
to accomplish the precision portions?   Are we supposed to re-cast every
constant at highest precision in every formula to make sure we don’t lose
data?
This doesn’t need to be done with Variables, why does it need to be done
with constants?
 
Please see my comments in the sample program. I hope it is readable, because
sometimes e-mail breaks lines where I don’t intend it to.
 
James
 
 
 
 
program Const_Vs_Var;
 
Const
   A_const = Integer(8427);
   B_const = Byte(33);
   C_const = Single(1440.5);
 
Var
   A_Var : Integer;
   B_Var : Byte;
   C_Var : Single;
   FF, GG, HH, II, JJ, KK, LL : Extended;
 
Begin
   A_Var := A_Const;
   B_Var := B_Const;
   C_Var := C_Const;
 
   FF := A_Var+B_Var/C_Var;  
   // This is the baseline, The math done with variables comes out the way I
expect it to.
 
   GG := Integer(A_Var)+Byte(B_Var)/Single(C_Var);
   // This is just for emphasis that I am doing the math with the data types
explicitly defined and I get the correct results.
 
   HH := Integer(A_Const)+Byte(B_Const)/Single(C_Const);
   // The result of this ONLY fits in an extended, and the Variable is
Extended, the constants are explicitly defined as above,  why is the
precision of the result reduced? 
 
   KK := A_Const+Extended(B_Const/C_Const);
   // Here I’m trying to define that the result of the division should be
stored as an extended.
 
   II := A_Const+B_Const/C_Const; 
   // I really expected this to work without all the typecasting, because
the constants are defined the way I want them to be. 
 
   JJ := Extended(A_Const+B_Const/C_Const);
   // Here I am explicitly defining the result of the calculation to be
Extended, why doesn’t this work?
 
   LL := Extended(A_Const)+Extended(B_Const)/Extended(C_Const);
   // This is what I need to do to get the results I want, but I don’t
understand why.  Why does the integer need to be converted to floating point
here?
 
 
   WRITELN ( ' A_const = ',A_Const) ;
   //  A_const = 8427  //Integer
 
   WRITELN ( '   A_var = ',A_Var) ;
  //A_var = 8427  //Integer
 
   WRITELN ( ' B_const = ',B_Const) ;
  //  B_const = 33//Byte
 
   WRITELN ( '   B_var = ',B_Var) ;
  //B_var = 33//Byte
 
   WRITELN ( ' C_const = ',C_Const: 20 : 20 ) ;
  //  C_const = 1440.5000 //Single
 
   WRITELN ( '   C_var = ',C_Var: 20 : 20 ) ;
  //C_var = 1440.5000 //Single
 
   WRITELN ( '  FF = ',FF:20:20 ,'  FF-FF = ',FF-FF:20:20) ; 
   //   FF = 8427.02290871225268987000  FF-FF = 0.
   //This is what I expect
 
   WRITELN ( '  GG = ',GG:20:20 ,'  FF-GG = ',FF-GG:20:20) ; 
   //   GG = 8427.02290871225268987000  FF-GG = 0.
   //This is what I expect
 
   WRITELN ( '  HH = ',HH:20:20 ,'  FF-HH = ',FF-HH:20:20) ; 
   //   HH = 8427.022460937500  FF-HH = 0.00044777475268986677
   //I don't understand why this is different from GG?  It's an Int + Byte /
Single and cast the same way
 
   WRITELN ( '  II = ',II:20:20 ,'  FF-II = ',FF-II:20:20) ; 
   //   II = 8427.022460937500  FF-II = 0.00044777475268986677
   //I don't understand why this is different from FF?  It's an Int + Byte /
Single
 
   WRITELN ( '  JJ = ',JJ:20:20 ,'  FF-JJ = ',FF-JJ:20:20) ; 
   //   JJ = 8427.022460937500  FF-JJ = 0.00044777475268986677 
   //Why doesn't this casting work?   I'm saying I want the result in an
Extended.
 
   WRITELN ( '  KK = ',KK:20:20 ,'  FF-KK = ',FF-KK:20:20) ; 
   //   KK = 8427.02290871180593967000  FF-KK = 0.044675019240
   //Why is this off a little?  I am casting the division to be Extended.
 
   WRITELN ( '  LL = ',KK:20:20 ,'  FF-LL = ',FF-LL:20:20) ; 
   //   LL = 8427.02290871180593967000  FF-LL = 0.
   //Why do I need to re-cast each constant as Extended? it’s not what I
really want, I want to add an integer to a byte divided by a single.. do it
correctly and store it as Extended.
 
End.
 
A_const = 8427
   A_var = 8427
B_const = 33
   B_var = 33
C_const = 1440.5000
   C_var = 1440.5000
  FF = 8427.02290871225268987000  FF-FF = 0.
  GG = 8427.02290871225268987000  FF-GG = 0.
  HH = 8427.022460937500  FF-HH = 0.00044777475268986677
  II = 8427.022460937500  FF-II = 0.00044777475268986677
  JJ = 8427.022460937500  FF-JJ = 0.00044777475268986677
  KK = 8427.02290871180593967000  FF-KK = 0.044675019240
  LL = 8427.02290871180593967000  FF-LL = 0.
 
 
 
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-13 Thread James Richters via fpc-pascal
It occurs to me that there is merit in reduction of precision to increase
performance, and so I'm trying to learn how to do this correctly, but the
thing that confuses me is that math with constants doesn't seem to be the
same as math with variables, and I don't know why.

It also looks to me like when there is an expression such as:
e := 8427.0 + 33.0 / 1440.0;
what is happening each term of the  expression is evaluated individually to
see if it can be reduced in precision, and then the math is carried out, but
if the math was carried out at full precision first by the compiler, THEN
the entire answer was evaluated to see if it can be reduced in precision,
the results would be what we are all expecting. 

Regardless of that however, when I am working with variables, an integer
added to a byte that has been divided by a single results in an
extended...it's legitimate to expect you could get an extended result from
such an operation, just as dividing a byte by another byte could result in
an extended answer.  With variables, this seems to always be the case, but
with constants, it does not seems to be the case.  If constants just did the
math the same as variables, then all this reduction in precision stuff would
work flawlessly for everyone without re-casting everything.

Please consider the code below, I am comparing the results to what I get
when I perform this math with the Windows Calculator, as you can see no
matter how I cast it, when using variables, I get the expected answer, but
when the compiler does the math, it's not working the same way. 
What seems to be happening with variables is that the answer to lower
precision entities can result in higher precision results, while with
constants, the resulting precision is limited in some way, but in a way I
don't understand, because it's being reduced to single precision, but the
lowest precision element is a byte.

In other words with variables a byte / single is perfectly capable of
producing an extended result, without re-casting.  But with constants doing
the exact same thing forces the result to always be a single.

I don't think the real issue has anything to do with this reduction in
precision at all, I think it has to do with whatever causes the compiler to
do math differently than the executing program does with variables.  I don't
understand why I must individually re-cast every element of the equation
using constants to extended, while when I do the exact same thing with
variables it's not necessary. 

I am wondering if the way the compiler does the math, it's is expecting that
all constants would be full precision, and therefore the way it did the math
before always came out right, but when the change was made in 2.2 to reduce
the precision to variables, no corresponding adjustment was made to the way
the compiler carries out math to compensate for the possibility that there
was such a thing as a constant with reduced precision.   So the compiler is
doing math as if all input terms are at highest precision, therefore not
needing to bother considering the answer might be higher precision than the
input terms, but now that there is the possibility of the result being of
higher precision, some adjustment to the way math is done by the compiler is
necessary. 

I just think if the compiler did all the math the same way the executing
program does with math with variables, then everything is solved for
everyone... without any re-casting or unexpected results due to division,
and while also preventing unnecessary precision.  this has nothing to do
with the reduction of precision, only the way the compiler is doing it's
calculations needs to be adjusted for this new situation.

Just fixing the way the compiler does the math also requires no knowledge of
the left side of the equation by the right.  The compiler just needs to do
the calculations the same way as variables are calculated with the extra
step of re-evaluating to see if the precision can be reduced when it's done.

James

program Const_Vs_Var;

Const
   A_const = Integer(8427);
   B_const = Byte(33);
   C_const = Single(1440.5);
   Win_Calc = 8427.0229087122526900381811870878;
   Const_Ans = A_Const+B_Const/C_Const;

Var
   A_Var : Integer;
   B_Var : Byte;
   C_Var : Single;
   Const_Ans1, Const_Ans2, Const_Ans3, Var_Ans1, Var_Ans2, Var_Ans3 :
Extended;

Begin
   A_Var := A_Const;
   B_Var := B_Const;
   C_Var := C_Const;

   Var_Ans1   := A_Var+B_Var/C_Var;
   Const_Ans1 := A_Const+B_Const/C_Const;
   Var_Ans2   := Integer(A_Var)+Byte(B_Var)/Single(C_Var);
   Const_Ans2 := Integer(A_Const)+Byte(B_Const)/Single(C_Const);
   Var_Ans3   := Extended(A_Var)+Extended(B_Var)/Extended(C_Var);
   Const_Ans3 := Extended(A_Const)+Extended(B_Const)/Extended(C_Const);

   WRITELN ( '   Win_Calc = ',   Win_Calc:20:20) ;
   WRITELN ( '  Const_Ans = ',  Const_Ans:20:20 ,'  Win_Calc-Const_Ans =
',Win_Calc-Const_Ans:20:20) ;
   WRITELN ( ' Const_Ans1 = ', Const_Ans1:20:20 ,' Win_Calc-Const_Ans1

Re: [fpc-pascal] Floating point question

2024-02-09 Thread James Richters via fpc-pascal
>However, adding support for an option called -CFMax or similar should be no
problem.

It would be VERY much appreciated!

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-09 Thread James Richters via fpc-pascal
>Because 1440.1 cannot be represented exactly as a single precision floating
point number. Nor as a double or extended precision floating point >number
for that matter, and in that case the compiler uses the maximum precision is
supported by the target platform.

I see that now, I think someone pointed out that 1440.5 would also be a
problem since it fits in a single.

So my idea of trying to change all the x.0s to x only helps some cases, not
all cases, as I can't change x.5 to anything quickly with a global search.
There could be anything that happens to fit in a single, making my Extended
calculation come out to a Single.

How does one get the old behavior for programs that use Extended without
analyzing and re-writing thousands of lines of code?

Is there any way we can please get -CF80 or {$MINFPCONSTPREC 80} or some
other way to turn off the new behavior for applications that use Extended.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-06 Thread James Richters via fpc-pascal
for trouble.   Nobody uses Doubles or 
Extended in a program because they want low precision results.


James


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-06 Thread James Richters via fpc-pascal
>Jonas has argued, not without reason, that calculating everything always at
full precision has its disadvantages too.

I agree with that, and I do see the value in reducing the precision when it
is possible, but not when it's causing data loss. 
The intention is perfectly fine, it's the execution that has a bug in it. 

I think that any reasonable person reading the following code would conclude
that FF, GG, HH, and II should be exactly the same.  I am defining
constants, in FF I define variables of the same type to the constants, and
it comes out correctly, in GG I use the constants directly, and its wrong.
There is nothing about this that any programmer should understand because
it's a bug. 

FF and GG are both adding an integer to a byte divided by a single, there is
no difference to any reasonable programmer between what FF and GG are
saying, and the programmer should not have to resort to ridiculous
typecasting as in II to get almost the correct answer, but is still wrong.
By the way notice that even with the casting, it's still wrong. 
II SHOULD have produced the right answer, because it's perfectly legitimate
to divide a byte by a single and expect the answer to be an extended. 

program Constant_Bug;

Const
   A_const = Integer(8427);
   B_const = Byte(33);
   C_const = Single(1440.0);

Var
   A_Var : Integer;
   B_Var : Byte;
   C_Var : Single;
   FF, GG, HH, II : Extended;

begin
   A_Var := A_Const;
   B_Var := B_Const;
   C_Var := C_Const;

   FF := A_Var+B_Var/C_Var;
   GG := A_Const+B_Const/C_Const;
   HH := Extended(A_Const+B_Const/C_Const);
   II := Extended(A_Const+Extended(B_Const/C_Const));

   WRITELN ( ' FF = ',FF: 20 : 20 ) ;
   WRITELN ( ' GG = ',GG: 20 : 20 ) ;
   WRITELN ( ' HH = ',HH: 20 : 20 ) ;
   WRITELN ( ' II = ',II: 20 : 20 ) ;
end.

 FF = 8427.022916625000
 GG = 8427.022460937500
 HH = 8427.022460937500
 II = 8427.02291666716337204000

FF and II are correct, GG and HH are wrong.   I understand now WHY this is
happening, but I argue, that it's not obvious to anyone that it should be
happening, it's just a hidden known bug waiting to bite you.  No reasonable
programmer would think that FF and GG would come out differently,  the
datatypes are all defined legitimately, and the same, the results should
also be the same.

In my opinion the changes in v2.2 break more things than they fix, and
should be reverted, and used ONLY if asked for by a compiler directive, we
should not have to do special things to get it to work correctly.  If you
give the compiler directive to use this feature, then you know you might
have to cast some things yourself, but to apply this globally and then
require a directive to not do it, is just not right, unless ALL code can be
run the way it did pre 2.2 without modification,  this is CLEARLY not the
case.   

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question (Rafael Picanço)

2024-02-06 Thread James Richters via fpc-pascal
This is my opinion from my testing, but others may have something else to say.
 
1) Does it affects constants only? 
Not really, if you set a variable with constant terms, it is affected, if you 
set a variable with other variables, it is not affected.
Cont
   Mycontant := 8432+33/1440.0;//Is affected;
Var
   MyDoubleVariable:Double;
 
MyDoubleVariable := 8432+33/1440.0;   //Is affected
 
 
Var
   MyInteger : Ineger;
   MyByte :  Byte
   MySingle : Single;
   MyDouble : Double;
 
MyInteger := 8432;
MyByte := 33;
MySingle := 1440.0;
MyDouble := MyInteger + MyByte / MySingle; //   is NOT affected;
 
 
2) Does it affects the LargerFloat type?  
I don’t know what you mean by LargerFloat, but Double an d Extended are 
affected, and even Real if your platform defines Real as a Double.
Anything that is not Single precision is affected.
 
3) Should I use {$MINFPCONSTPREC 64} in {$mode objfpc} too to avoid it?   
Everyone should use {$MINFPCONSTPREC 64} in all programs until the bug is 
fixed, unless you use extended, then you have no good solution. Because you 
can’t set it to 80.


4) BONUS: Is the LargerFloat type really the larger, or should one do something 
else?  
I’m afraid I don’t qualify for the bonus, because I don’t know what LargerFloat 
is.
 
James
 
 
 
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-06 Thread James Richters via fpc-pascal
What's apparently happening now is:
MyExtended := ReducePrecisionIfNoLossOfData (8246) +
ReducePrecisionIfNoLossOfData (33.0) / ReducePrecisionIfNoLossOfData
(1440.0);
But it is not being done correctly, the 1440.0 is not being reduced all the
way to an integer, because it was, everything would work.  The 1440.0 is
being considered a single, and the division is also being now considered a
single, even though that is incorrect.   But 1440.1 is not being considered
a single, because 1440.1 is not breaking everything.

What should be happening is:
MyExtended := ReducePrecisionIfNoLossOfData(8246+33.0/1440.0);


I just realized something...  regardless of when or how the reduction in
precision is happening, the bug is different than that,  because the result
of a byte divided by a single when stored in a double is a double, NOT a
single,  there should be no problem here, there is a definite bug. 

Consider this:
program TESTDBL1 ;

Const
   HH = 8427.02291667;
Var
   AA : Integer;
   BB : Byte;
   CC : Single;
   DD : Single;
   EE : Double;
   FF : Extended;
   GG : Extended;
   

begin
   AA := 8427;
   BB := 33;
   CC := 1440.0;
   DD := AA+BB/CC;
   EE := AA+BB/CC;
   FF := AA+BB/CC;
   GG := 8427+33/1440.0;
   
   WRITELN ( 'DD = ',DD: 20 : 20 ) ;
   WRITELN ( 'EE = ',FF: 20 : 20 ) ;
   WRITELN ( 'FF = ',FF: 20 : 20 ) ;
   WRITELN ( 'GG = ',GG: 20 : 20 ) ;
   WRITELN ( 'HH = ',HH: 20 : 20 ) ;
end.

When I do the division of a byte by a single and store it in an extended, I
get the division carried out as an extended.
FF, GG, and HH should all be exactly the same if there is not a bug.
But:

DD = 8427.02246100
EE = 8427.022916625000
FF = 8427.022916625000
GG = 8427.022460937500
HH = 8427.022916625000

GG,  the one with constants, is doing it wrong... 

If the entire formula was calculated the original way at full precision,
then only result was reduced if there was no loss in precision right before
storing as a constant,  then this solves the problems for everyone, and this
is the correct way to do this.  Then everyone is happy, no Delphi warnings,
no needlessly complex floating point computations if the result of all the
math is a byte, and no confusion as to why it works with 1440.1 and not
1440.0  Compatibility with all versions of Pascal,  etc..  

This calculation is only done once by the compiler, the calculation should
be done at full possible precision and only the result stored in a reduced
way if it makes sense to do so.

The problem I have with the changes made with v2.2, is that it's obvious
that the change was going to introduce a known bug at the time:
"Effect: some expressions, in particular divisions of integer values by
floating point constants, may now default to a lower precision than in the
past."
How is this acceptable or the default?? 

"Remedy: if more precision is required than the default, typecast the
floating point constant to a higher precision type, e.g. extended(2.0).
Alternatively, you can use the -CF command line option to change the default
precision of all floating point constants in the compiled modules."

The first remedy is unreasonable, I should not have to go through thousands
of lines of code and cast my constants, it was never a requirement of Pascal
to do this. 

Great if -CF80 worked, but even if you are happy with -CF64, my problem is:
how is anyone coming into FPC after 2.2 supposed to know that their
constants that always worked before are going to no longer be accurate??

The better thing to do would be to do it RIGHT before releasing the change
so that it can't be a problem for anyone, and make:
"New behaviour: floating point constants are now considered to be of the
lowest precision which doesn't cause data loss"  a true statement.

If the entire formula was evaluated at full precision, and only the result
was stored as a lower precision if possible, then there is never a problem
for anyone.


James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-06 Thread James Richters via fpc-pascal
I have the exact same intuition and expectation.  

I think this whole issue is easy to fix, just detect the .0s and cast them
to integers by default instead of singles, because then everything does work
fine.

If I had a clue where the code for this might reduction in precision might
be, I would try to fix it, but it's way over my head I'm afraid.   I think
the intention and theory behind doing it the new way is great, it just has
this one flaw in it that could be fixed so the true behavior matches what is
in the documentation,  that things will be reduced that would not cause a
loss in precision.   That is true for almost all cases except when you put a
.0 then it fails... it's losing precision. Reducing the .0 to an integer
solves the problem... and I think if you had X = 2.0 it would be reduced to
an integer or a byte, it's just when it's in a formula that it's getting set
to a single, and that single is throwing everything off... it just wasn't
reduced far enough. 

James

-Original Message-
From: fpc-pascal  On Behalf Of
Thomas Kurz via fpc-pascal
Sent: Tuesday, February 6, 2024 7:53 AM
To: 'FPC-Pascal users discussions' 
Cc: Thomas Kurz 
Subject: Re: [fpc-pascal] Floating point question

Well, this is funny because I *did* compile it on DOS with Turbo Pascal 5.5,
and I got the correct result there. Cross-compiling with FPC to msdos target
gave the "wrong" (aka unexpected) result again. There were so many factors
involved which caused great confusion.

>From my point of view, an expression being an assigned to a variable of type
"double" should be evaluated with double precision, not single. This is
obviously the way integers are handled by internally using int64. A few
weeks ago, I had incosistent behavior between x64 and x86 modes and it
turned out that 32-bit code did internal castings to int64 thus resulting in
the expected value whereas 64-bit cannot cast to int128 (because there is no
int128) and thus gives an unexpected result (well, at least to me). So my
intuition would (and obviously did!) expect double precision throughout the
calculation.

Kind regards,
Thomas



- Original Message -
From: James Richters 
To: 'FPC-Pascal users discussions' 
Sent: Tuesday, February 6, 2024, 13:44:37
Subject: [fpc-pascal] Floating point question

I don't think you were doing anything wrong, that's what I am simply trying
to point out.  If you ran your code on Turbo Pascal 7.0, you would not have
an issue, it would be fine.  There is no reason for a programmer to expect
this behavior and it's very confusing when it does come up.

There is a bug here and it should be acknowledged instead of defended.
Discovering bugs is a good thing, it can lead to improvements to make the
system better for everyone, but only if the discovery is learned from and
acted upon.  I'm sure everyone here can relate to how frustrating it can be
to encounter a bug and have no idea whatsoever what the problem is.
Undiscovered bugs are much worse than those which have been figured out.  

I think this is one that can be very frustrating for a lot of people, and
it's very difficult to figure out what's happening,  because everything
happens correctly >99.9% of the time.  If you put anything from x.001 to
x.999 it has no problem, if you put x.0, you have a problem.  Put as many
decimals as you like to see why there is no reason why any programmer should
expect this behavior.   On top of that x has no problem, and many
programmers use x.0 when x would have been fine, they are just in the habit
of putting the .0 and in Turbo Pascal, there was never a problem with doing
this. 

I am glad we at least have an explanation, but how many others are going to
need to re-discover this issue that should not even be an issue?  
It can still be a problem for people who didn't happen to come across this.
I didn't expect it to be an issue.  While compiling with -CF64 or using
{$MINFPCONSTPREC 64}  fixes it for programs that use doubles, there is no
good solution I can find for programs that use extended, because you can't
put 80 into either of those.  So for extended programs the only solution I
can think of at the moment is to go through the WHOLE thing and replace all
the x.0's with x  Which I have started doing but it's a tedious chore. 

I appreciate the discussion here, because I had noticed inaccuracies from
time but I was never able to get far enough in to realize this is what was
happening.   It's very frustrating indeed and I think if something can be
done to save others this frustration and unexpected behavior, it would be
helpful.

James

-Original Message-
From: fpc-pascal  On Behalf Of
Thomas Kurz via fpc-pascal
Sent: Tuesday, February 6, 2024 6:59 AM
To: 'FPC-Pascal users discussions' 
Cc: Thomas Kurz 
Subject: Re: [fpc-pascal] Floating point question

I'd like to apologize, because my intention hasn't been to raise controverse
discussions. I'm very thankful about the explanation. 

Re: [fpc-pascal] Floating point question

2024-02-06 Thread James Richters via fpc-pascal
I don't think you were doing anything wrong, that's what I am simply trying
to point out.  If you ran your code on Turbo Pascal 7.0, you would not have
an issue, it would be fine.  There is no reason for a programmer to expect
this behavior and it's very confusing when it does come up.

There is a bug here and it should be acknowledged instead of defended.
Discovering bugs is a good thing, it can lead to improvements to make the
system better for everyone, but only if the discovery is learned from and
acted upon.  I'm sure everyone here can relate to how frustrating it can be
to encounter a bug and have no idea whatsoever what the problem is.
Undiscovered bugs are much worse than those which have been figured out.  

I think this is one that can be very frustrating for a lot of people, and
it's very difficult to figure out what's happening,  because everything
happens correctly >99.9% of the time.  If you put anything from x.001 to
x.999 it has no problem, if you put x.0, you have a problem.  Put as many
decimals as you like to see why there is no reason why any programmer should
expect this behavior.   On top of that x has no problem, and many
programmers use x.0 when x would have been fine, they are just in the habit
of putting the .0 and in Turbo Pascal, there was never a problem with doing
this. 

I am glad we at least have an explanation, but how many others are going to
need to re-discover this issue that should not even be an issue?  
It can still be a problem for people who didn't happen to come across this.
I didn't expect it to be an issue.  While compiling with -CF64 or using
{$MINFPCONSTPREC 64}  fixes it for programs that use doubles, there is no
good solution I can find for programs that use extended, because you can't
put 80 into either of those.  So for extended programs the only solution I
can think of at the moment is to go through the WHOLE thing and replace all
the x.0's with x  Which I have started doing but it's a tedious chore. 

I appreciate the discussion here, because I had noticed inaccuracies from
time but I was never able to get far enough in to realize this is what was
happening.   It's very frustrating indeed and I think if something can be
done to save others this frustration and unexpected behavior, it would be
helpful.

James

-Original Message-
From: fpc-pascal  On Behalf Of
Thomas Kurz via fpc-pascal
Sent: Tuesday, February 6, 2024 6:59 AM
To: 'FPC-Pascal users discussions' 
Cc: Thomas Kurz 
Subject: Re: [fpc-pascal] Floating point question

I'd like to apologize, because my intention hasn't been to raise controverse
discussions. I'm very thankful about the explanation. From the beginning, I
knew that the error was on my side, but I didn't know *what* I'm doing
wrong.

Again, thanks for helping.

Kind regards,
Thomas



- Original Message -
From: James Richters via fpc-pascal 
To: 'FPC-Pascal users discussions' 
Sent: Sunday, February 4, 2024, 18:25:39
Subject: [fpc-pascal] Floating point question

I agree with Aadrian 100%
 
"New behaviour: floating point constants are now considered to be of the
lowest precision which doesn't cause data loss"

We are getting data loss So it's doing it WRONG.

So we are all living with a stupid way of doing things so some Delphi code
won't have warnings?

Who came up with this???

The old way was CORRECT,   instead of changing it for everyone making it
wrong for most users, a compiler directive should have been needed to get
rid of the warnings, or ONLY applied in Mode Delphi.  Not to make everything
incorrect for everyone unless you add a directive. The problem with this
that no one is expecting to need to add a directive to do things right. 

Consider this:
 
Var
  MyVariable : Extended;

MyVariable := 8427 + 33 / 1440.0;

Since I am storing the result in an Extended, I DO NOT EXPECT the 33/1440 to
be a SINGLE, that is NUTS!!
I expect it to be all done in Extended. Why would anyone expect the contents
of MyVariable to be butchered by storing the 33/1440 in single precision.

In other words
I expect the result of these both to be the same:

program TESTDBL1 ;

Var
AA : Extended;
BB : Extended;
CC : Extended;
DD : Extended;
EE : Extended;

begin
   AA := 8427;
   BB := 33;
   CC := 1440.0;
   DD := AA+BB/CC;
   EE := 8427+33/1440.0;
   WRITELN ( 'DD =' , DD : 20 : 20 ) ;
   WRITELN ( 'EE =' , EE : 20 : 20 ) ;
end.

But they are NOT
DD =8427.022916625000
EE =8427.022460937500

EE is WRONG and can never be considered right.   Why would ANY user with the
code above expect that the 33/1440 would be done as a single, thus causing a
loss of precision. 

Again:
"New behaviour: floating point constants are now considered to be of the
lowest precision which doesn't cause data loss"

This was NOT done in the lowest precision which doesn't cause data loss.. we
lost data   We are no longer Extended precision, anything at all we use
EE for is WRONG.

[fpc-pascal] FW: Floating point question

2024-02-05 Thread James Richters via fpc-pascal
Sorry if this ends up being a duplicate, but I thought since it did not show
up after a few hours that is was blocked because I had attached a screen
shot to it.  So here I removed the attachment and instead link to the screen
shot:
https://drive.google.com/file/d/1IJWSqR8UYgWRoq9oVwuOSa-XFd35FXZP/view?usp=s
haring

James

-Original Message-
From: James Richters  
Sent: Monday, February 5, 2024 7:26 AM
To: 'FPC-Pascal users discussions' 
Subject: RE: [fpc-pascal] Floating point question

I ran this program in Borland Turbo Pascal 7.0 for DOS, and it does not have
this problem.  AA, BB, and CC all produce identical results, But FPC, even
with {$Mode TP},  produces different results if I use 1440 vs 1440.0 I guess
Delphi compatibility is more important than Turbo Pascal compatibility even
if I am in Turbo Pascal Mode?
I wonder if Delphi even has this bug.  

I propose that all modes should use the old way and only Mode Delphi should
do it the other way, Or better yet require a switch to allow the reduction
in precision, instead of always doing it and requiring a switch to turn it
off, because if you are using extended, you can't effectively turn it off as
there is no -CF80, or best of all figure out why it's a bug, and fix the
bug.   The bug is that using something like 1440.0 causes single precision
and a loss of data, while 1440 or 1440.1, or anything else that isn't .0
does not have this problem.   Precision should never be sacrificed, and the
user should not have to do something special to protect against a reduction
in precision. 

When I learned Turbo Pascal back in the 90's this was never a thing, I never
needed to cast my constants to prevent low precision results.  It wasn't in
my Turbo Pascal text book in technical school, because it didn't need to be,
constants were always evaluated at full precision. 

Delphi came along and did something which could make sense in certain
circumstances, and I agree it's probably an improvement, but it's being
implemented slightly incorrectly. The stipulation that precision is reduced
to the lowest precision that doesn't cause data loss is not being followed,
we are getting data loss.

I don't know if Delphi got it right, because I don't have Delphi, but there
seems to be a real bug here. We should not be getting Data Loss, and things
I have done for decades should still work the same as they used to, but they
are defiantly not working the way they used to. 

Below is the program I tested with, With TP7, I never get a reduction in
precision.  1440 and 1440.0 yield the same results, full precision
evaluation of constants, and the result is never 8427.0224... Unless I put
it into a variable defined as a single. Even then, there is never any
difference between AA, BB, or CC for any given variable type.

I could not cut and paste the results from TP7 because I am running it in
DosBox, and I can't copy and paste from the DosBox window, but I put the
screenshot as an attachment.  I don't know if images will go through the
mailing list, if not, I'll put it somewhere and link it. 

My argument is that I never needed to cast my constants before to avoid a
loss in precision, it never even crossed my mind to think I would have to do
that, it's not the way Pascal works.  In Turbo Pascal if I do
Writeln(33/1440); and Writeln(33/1440.0);  I get the exact same thing.  In
FPC I get very different results.  I didn't need to cast the 1440.0 in Turbo
Pascal to prevent a loss of data, it's not necessary.
It may be the way Delphi works, but I doubt Delphi has the loss of precision
bug.  90% of my code was ported over from Turbo Pascal, I skipped Delphi and
didn't make a windows version until FPC, and I have a LOT of units with
{$Mode TP} that still have my original code.  I don't know if Turbo Pascal
reduced the precision of constants to gain performance, but I do know it was
never a problem, I never had a reduction in precision. 

I think it's great to make improvement like this, and I'm all for gaining
performance, but it needs to be implemented the way it was intended, and it
needs to work, there should be no loss of precision, and I should not have
to do something special to prevent the loss of precision, it should be
precise by default. 

James

program TESTDBL1 ;

Const
   AA = 8427+33/1440.0;
   BB = 8427+33/1440;
   CC = 8427.02291667;
Var
   A_Ext : Extended;
   B_Ext : Extended;
   C_Ext : Extended;
   A_Dbl : Double;
   B_Dbl : Double;
   C_Dbl : Double;
   A_Sgl : Single;
   B_Sgl : Single;
   C_Sgl : Single;

begin
   A_Ext := AA;
   B_Ext := BB;
   C_Ext := CC;
   A_Dbl := AA;
   B_Dbl := BB;
   C_Dbl := CC;
   A_Sgl := AA;
   B_Sgl := BB;
   C_Sgl := CC;

   WRITELN ( 'A_Ext = ',A_Ext: 20 : 20 ) ;
   WRITELN ( 'B_Ext = ',B_Ext: 20 : 20 ) ;
   WRITELN ( 'C_Ext = ',C_Ext: 20 : 20 ) ;
   WRITELN;
   WRITELN ( 'A_Dbl = ',A_Dbl: 20 : 20 ) ;
   WRITELN ( 'B_Dbl = ',B_Dbl: 20 : 20 ) ;
   WRITELN ( 'C_Dbl = ',C_Dbl: 20 : 20 ) ;
   WRITELN;
   WRITELN

Re: [fpc-pascal] Floating point question

2024-02-05 Thread James Richters via fpc-pascal
What is the proper way to use $EXCESSPRECISION ?   I tried:
 
program TESTDBL1 ;
{$EXCESSPRECISION ON}
 
Const
TT_Const = 8427 + 33 / 1440.0 ;
SS_Const = 8427 + Double(33 / 1440.0) ;
 
Begin
   WRITELN ( 'TT_Const = 8427 + 33 / 1440.0 ;   =' , 
TT_Const  : 20 : 20 ) ;
   WRITELN ( 'SS_Const = Double(8427 + 33 / 1440.0);=' , 
SS_Const  : 20 : 20 ) ;
end.
 
 
I get 
 
TT_Const = 8427 + 33 / 1440.0 ;   
=8427.02246100
SS_Const = Double(8427 + 33 / 1440.0);
=8427.0229166671634000
 
I expected them to be both the same. 
 
James
 
-Original Message-
From: fpc-pascal  On Behalf Of James 
Richters via fpc-pascal
Sent: Sunday, February 4, 2024 10:52 AM
To: 'FPC-Pascal users discussions' 
Cc: James Richters 
Subject: Re: [fpc-pascal] Floating point question
 
Hi Jonas,
That’s Interesting,  Thank you very much for the links!! Not only an 
explanation but a solution. 
The original is how I would expect it to work,  If it's for Delphi 
compatibility why not only do that when in Mode Delphi?   If not in mode Delphi 
who cares if it's compatible?
Delphi is completely wrong to do it this way.
I'm glad there is  $EXCESSPRECISION   I am Immediately putting that in every 
single program I have, because that is I always thought it would work, and I do 
have divisions where this can be a problem.
 
James
-Original Message-
From: fpc-pascal < <mailto:fpc-pascal-boun...@lists.freepascal.org> 
fpc-pascal-boun...@lists.freepascal.org> On Behalf Of Jonas Maebe via fpc-pascal
Sent: Sunday, February 4, 2024 7:21 AM
To:  <mailto:fpc-pascal@lists.freepascal.org> fpc-pascal@lists.freepascal.org
Cc: Jonas Maebe < <mailto:jo...@freepascal.org> jo...@freepascal.org>
Subject: Re: [fpc-pascal] Floating point question
 
On 03/02/2024 18:42, James Richters via fpc-pascal wrote:
> Constants are also evaluated wrong,you don’t know what that constant 
> is going to be used for, so all steps of evaluating a constant MUST be 
> done in extended by the compiler, or the answer is just wrong.
 
See
 <https://wiki.freepascal.org/User_Changes_2.2.0#Floating_point_constants> 
https://wiki.freepascal.org/User_Changes_2.2.0#Floating_point_constants
and  <https://www.freepascal.org/daily/doc/prog/progsu19.html> 
https://www.freepascal.org/daily/doc/prog/progsu19.html
fpc-pascal maillist  -   <mailto:fpc-pascal@lists.freepascal.org> 
fpc-pascal@lists.freepascal.org  
<https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal> 
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
I got the -CF argument to work... it's not just -CF, it's is -CF and then the 
limiting precision...
-CF32 for single, or -CF64 for double,   but it won't take -CF80 so Extended 
still doesn't come out right.

With -CF64 I get better results but it's not completely doing it the old way.
BB = 8427+33/1440.0;  comes out the same as doing:
BB = Extended(8427+Double(33/1440));  which is  8427.0229166678793000

But 
BB = 8427+33/1440; still comes out right:  8427.022916625000

I still can't get  $EXCESSPRECISION   to work.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
So I need to do this?
AA = Extended(8427+Extended(33/Extended(1440.0)));

That seems excessive when   BB = 8427+33/1440.1;   Has no problem

The thing I have an issue with is 
BB = 8427+33/1440.1; is done the way I want it to, and
BB = 8427+33/1440.01;   is done the way I want it to, and
BB = 8427+33/1440;is done the way I want it to, but
BB = 8427+33/1440.0; is done a different way.

To me these should all be done the same way.  And they would have all been done 
the same way before the 2.2 change, that change works for every case except 
when there is a .0,  A  .01 at the end is fine,  a .001234 at the end is fine, 
its JUST .0 that's not fine.

This is inconsistent,  why didn't the 1440.1 version reduce to a single?  It 
fits in a single, and I didn't specify it any differently than 1440.0.
This lack of consistency is that's leading me to think it's more of a bug..
Everything I put in the denominator, other than something that ends with .0 
works as I expect, it's ONLY when there is a .0 that things go wrong. 

Why is 1440.0 different that 1440.1? 

Say I have a program with some constants at the top, and the program has been 
working flawlessly for years, and now I change one
Constant from something with a .001 in the denominator to a .000 in the 
denominator,  I know it's lazy, just change the 1 to a 0 and don't delete the 
useless 0's after the decimal point, , but now I have all kinds of imprecision, 
but if I would have changed it to .001 instead, it is still fine, and 
anything other than .0 is fine.  Why is .0 special and .1 is not?

Having one single way to do it that causes drastically differently results is a 
bug,  it should be consistent.  That way when I'm testing I will see that I 
need to cast the denominator as an extended and it will always work the same 
way.   It's this working different ways with nearly the same input that I have 
an issue with.When I learned Turbo Pascal in technical school, no one EVER 
said you need to cast your constants, and it wasn't in the text book either.   

All of my examples above should be processed the same way,  if 1440.1 doesn't 
force single precision, then 1440.0 should not force single precision either. 

James

-Original Message-
From: fpc-pascal  On Behalf Of Jonas 
Maebe via fpc-pascal
Sent: Sunday, February 4, 2024 5:25 PM
To: fpc-pascal@lists.freepascal.org
Cc: Jonas Maebe 
Subject: Re: [fpc-pascal] Floating point question

On 04/02/2024 23:21, James Richters via fpc-pascal wrote:
> Shouldn’t this do all calculations as Extended?
> 
> AA = Extended(8427+33/1440.0);

No, this only tells the compiler to interpret the result as extended.


Jonas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org 
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
Shouldn’t this do all calculations as Extended?
 
   AA = Extended(8427+33/1440.0);
 
It does NOT
 
Const
   AA = Extended(8427+33/1440.0);
   BB = 8427+33/1440;
   CC = 8427.02291667;
 
 
A_Ext = 8427.022460937500
B_Ext = 8427.022916625000
C_Ext = 8427.022916625000
 
A_Dbl = 8427.022460937500
B_Dbl = 8427.022916668000
C_Dbl = 8427.022916668000
 
A_Sgl = 8427.02246100
B_Sgl = 8427.02246100
C_Sgl = 8427.02246100
 
 
James
 
 
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
>> Not specifying in a program, specially in a strict programming language like 
>> Pascal, will always result in implementation depending 
>> variations/assumptions.
 
The problem is, I feel that I DID specify what should be by declaring my 
variable as Extended.   And Apparently FPC agrees with me, because it DOES work 
the way I expect, except if I put a .0 in my constant terms.   This is all just 
a bug if you put .0 after any integers in an expression.  I just put a better 
example that shows how it works correctly except if you put a .0

Strangely, upon discovering this, the solution is opposite what I thought it 
should be.  If all the terms of an expression were reduced to the lowest 
precision possible without loosing data, then my 1440.0 would be reduced from a 
float to a word, and then the entire problem would have went away, because when 
I put in 1440 without the .0, there is no problem.The .0 is apparently 
defining it to be a floating point and the smallest floating point is a single… 
but that’s not the smallest data structure, the smallest data structure that 
can be used is a word and that would have solved it. 
 
James
 
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
Here is a more concise example that illustrates the issue.   For me, being a
human, I see 1440 and 1440.0 as exactly the same thing, but they are not
acting as the same thing, and the 1440.0 is causing all the grief here.
See how it makes a difference whether the .0 is there or not.

Then replace the 1440.1, and notice how it's no longer an issue, note it's
only a problem with .0  if it's a .1, or anything other than .0, it seems
fine.

program TESTDBL1 ;

Const
   AA = 8427+33/1440.0;
   BB = 8427+33/1440;
   CC = 8427.02291667;   //Windows Calculator
Var
   A_Ext : Extended;
   B_Ext : Extended;
   C_Ext : Extended;
   A_Dbl : Double;
   B_Dbl : Double;
   C_Dbl : Double;
   A_Sgl : Single;
   B_Sgl : Single;
   C_Sgl : Single;

begin
   A_Ext := AA;
   B_Ext := BB;
   C_Ext := CC;
   A_Dbl := AA;
   B_Dbl := BB;
   C_Dbl := CC;
   A_Sgl := AA;
   B_Sgl := BB;
   C_Sgl := CC;

   WRITELN ( 'A_Ext = ',A_Ext: 20 : 20 ) ;
   WRITELN ( 'B_Ext = ',B_Ext: 20 : 20 ) ;
   WRITELN ( 'C_Ext = ',C_Ext: 20 : 20 ) ;
   WRITELN;
   WRITELN ( 'A_Dbl = ',A_Dbl: 20 : 20 ) ;
   WRITELN ( 'B_Dbl = ',B_Dbl: 20 : 20 ) ;
   WRITELN ( 'C_Dbl = ',C_Dbl: 20 : 20 ) ;
   WRITELN;
   WRITELN ( 'A_Sgl = ',A_Sgl: 20 : 20 ) ;
   WRITELN ( 'B_Sgl = ',B_Sgl: 20 : 20 ) ;
   WRITELN ( 'C_Sgl = ',C_Sgl: 20 : 20 ) ;
end.

A_Ext = 8427.022460937500
B_Ext = 8427.022916625000
C_Ext = 8427.022916625000

A_Dbl = 8427.022460937500
B_Dbl = 8427.022916668000
C_Dbl = 8427.022916668000

A_Sgl = 8427.02246100
B_Sgl = 8427.02246100
C_Sgl = 8427.02246100

Notice for Double and Extended they are getting the value for Single for the
division, throwing off the result, but only with 1440.0, not with 1440

With the constants defined as:
Const
   AA = 8427+33/1440.10;
   BB = 8427+33/1440.1;
   CC = 8427.0229150753419901395736407194;   //Windows Calculator

Now notice:

A_Ext = 8427.02291507534198978000
B_Ext = 8427.02291507534198978000
C_Ext = 8427.02291507534198978000

A_Dbl = 8427.0229150753421000
B_Dbl = 8427.0229150753421000
C_Dbl = 8427.0229150753421000

A_Sgl = 8427.02246100
B_Sgl = 8427.02246100
C_Sgl = 8427.02246100

All versions of Extended, Double, and Single are identical. As expected.
Everything I try works, except for .0

James


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
>No need to yell.
Yes, that's true, I apologize, I did not mean to come across that way.  

>This is how reasonable programing languages work. The result type depends
only on the type of the involved variables/expressions. *Never* the variable
it is assigned to.

If it's never defined by the variable it's assigned to, then maximum
precision should be used, because you don't know how it will be used.

I understand that the result depends on the variables and expressions,
The problem with constants used in an expression is that some determination
needs to be made because it's not specified.
Since it's not specified, then I think it should be implied to be the same
as the variable it would be stored in, if that determination cannot be made,
then maximum precision should be used.

In fact sometimes it does use the precision of the variable being assigned
to look at this:

program TESTDBL1 ;

Var
AA : Extended;
BB : Extended;
CC : Extended;
DD : Extended;
EE : Extended;
FF : Extended;
GG : Double;
HH : Single;

begin
   AA := 8427;
   BB := 33;
   CC := 1440.0;
   DD := AA+BB/CC;
   EE := 8427+33/1440.0;
   FF := 8427+33/1440;
   GG := 8427+33/1440;
   HH := 8427+33/1440;
   WRITELN ( 'DD =' , DD : 20 : 20 ) ;
   WRITELN ( 'EE =' , EE : 20 : 20 ) ;
   WRITELN ( 'FF =' , FF : 20 : 20 ) ;
   WRITELN ( 'GG =' , GG : 20 : 20 ) ;
   WRITELN ( 'HH =' , HH : 20 : 20 ) ;
end.

DD =8427.022916625000
EE =8427.022460937500
FF =8427.022916625000
GG =8427.022916668000
HH =8427.02246100

For FF, GG, and HH, I did not put the .0, so it must have made them al
integers... but now the division is carried out in the way that makes sense
for the variable it's being stored in,  it's only when I force the 1440 to
be a float by putting the .0 on that it gets it wrong. 
But if it was supposed to be 1440.1 then I couldn't leave the .1 off and
maybe I still have the issue but no.. I  DON'T have it... it's only
getting it wrong if it's 1440.0

Look at THIS:


program TESTDBL1 ;

Var
AA : Extended;
BB : Extended;
CC : Extended;
DD : Extended;
EE : Extended;
FF : Extended;
GG : Double;
HH : Single;

begin
   AA := 8427;
   BB := 33;
   CC := 1440.0;
   DD := AA+BB/CC;
   EE := Extended(8427+Extended(33/Extended(1440.1)));
   FF := 8427+33/1440.1;
   GG := 8427+33/1440.1;
   HH := 8427+33/1440.1;
   WRITELN ( 'DD =' , DD : 20 : 20 ) ;
   WRITELN ( 'EE =' , EE : 20 : 20 ) ;
   WRITELN ( 'FF =' , FF : 20 : 20 ) ;
   WRITELN ( 'GG =' , GG : 20 : 20 ) ;
   WRITELN ( 'HH =' , HH : 20 : 20 ) ;
end.

DD =8427.022916625000
EE =8427.02291507534198978000
FF =8427.02291507534198978000
GG =8427.0229150753421000
HH =8427.02246100

Just FYI, windows calculator gives 8427.0229150753419901395736407194 so I
expect to get the following for this:
FF =8427.02291507534198978000
GG =8427.0229150753421000
HH =8427.02246100
And YES that is what I get.

Things are only broken if I put 1440.0  there is a bug in this condition.

   FF := 8427+33/1440.0;
   GG := 8427+33/1440.0;
   HH := 8427+33/1440.0;

Windows calculator gets: 8,427.02291667
I expect to get:
FF =8427.022916625000
GG =8427.022916668000
HH =8427.02246100

But no, I get:
FF =8427.022460937500
GG =8427.022460937500
HH =8427.02246100


If I leave off the .0 then it's correct:
   FF := 8427+33/1440;
   GG := 8427+33/1440;
   HH := 8427+33/1440;

FF =8427.022916625000
GG =8427.022916668000
HH =8427.02246100


I feel much better about it all now.. I think it's SUPPOSED to work the way
I expect, but there is a bug if you put something like 1440.0 in your
constant expression.

Sorry again for my earlier tone.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
I can understand storing the constant in the lowest precision that doesn't 
cause data loss, thus making thing more efficient, but the actual calculation 
done by the compiler should be done at maximum precision and only the final 
result stored in the lowest required precision.
This calculation is only carried out buy the compiler once, during compilation, 
not by the executing program.

The calculation should be done completely using extended, and if the result of 
the entire calculation is a 2, then store it as a byte, if it's 1.23 then store 
it as a single, and if it's 1.2324241511343 store it as Extended.   The problem 
is the 33/1440 is being stored as a single and IS LOSING DATA, the division 
should have been detected and therefore the lowest precision that doesn't cause 
data loss is NOT a single.   

In all cases in our example, we should not be getting different values for the 
same constant.   The implementation not the right way of doing it.  It's not 
doing what is required by the statement:

"New behaviour: floating point constants are now considered to be of the lowest 
precision which doesn't cause data loss"

The "New behaviour"  has a DEFINATE bug in it, because we are experiencing data 
loss. 

The correct way to implement this is to have the compiler ALWAYS evaluate 
everything at highest precision, THEN after all computations are complete 
evaluate the final answer to store in the constant and reduce the precision of 
only the constant if it's justified.   If it was done this way then it would 
always give the expected result.

James


-Original Message-
From: fpc-pascal  On Behalf Of Florian 
Klämpfl via fpc-pascal
Sent: Sunday, February 4, 2024 8:20 AM
To: FPC-Pascal users discussions 
Cc: Florian Klämpfl 
Subject: Re: [fpc-pascal] Floating point question



> Am 04.02.2024 um 13:50 schrieb Adriaan van Os via fpc-pascal 
> :
> 
> Jonas Maebe via fpc-pascal wrote:
>> On 03/02/2024 18:42, James Richters via fpc-pascal wrote:
>>> Constants are also evaluated wrong,you don’t know what that constant is 
>>> going to be used for, so all steps of evaluating a constant MUST be done in 
>>> extended by the compiler, or the answer is just wrong.
>> See 
>> https://wiki.freepascal.org/User_Changes_2.2.0#Floating_point_constan
>> ts and https://www.freepascal.org/daily/doc/prog/progsu19.html
> 
> I think this discussion shows that the 2.2 compiler change was a bad idea 
> (for modes other than Delphi).

The result with the old code was that all floating point operations involving 
constants were carried out in full precision (normally double or extended) 
which is something unexpected and results in slow code.

Example:

const
  c2 = 2;
var
  s1, s2 : single;

…
s1:=s2/c2;

generated an expensive double division for no good reason.

OTOH:

const
  c2 : single = 2;
var
  s1, s2 : single;

…
s1:=s2/c2;

generated a single division.


 There is still the -CF option as a workaround to get the old behavior.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org 
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
How do I get -CF to work with the Text IDE?
I put -CF  and  just CF in "Additional Compiler Args"  either way I get:

Error: Illegal parameter: -CF   

James


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
I agree with Aadrian 100%
 
"New behaviour: floating point constants are now considered to be of the lowest 
precision which doesn't cause data loss"

We are getting data loss So it's doing it WRONG.

So we are all living with a stupid way of doing things so some Delphi code 
won't have warnings?

Who came up with this???

The old way was CORRECT,   instead of changing it for everyone making it wrong 
for most users, a compiler directive should have been needed to get rid of the 
warnings, or ONLY applied in Mode Delphi.  Not to make everything incorrect for 
everyone unless you add a directive. The problem with this that no one is 
expecting to need to add a directive to do things right. 

Consider this:
 
Var
  MyVariable : Extended;

MyVariable := 8427 + 33 / 1440.0;

Since I am storing the result in an Extended, I DO NOT EXPECT the 33/1440 to be 
a SINGLE, that is NUTS!!
I expect it to be all done in Extended. Why would anyone expect the contents of 
MyVariable to be butchered by storing the 33/1440 in single precision.

In other words
I expect the result of these both to be the same:

program TESTDBL1 ;

Var
AA : Extended;
BB : Extended;
CC : Extended;
DD : Extended;
EE : Extended;

begin
   AA := 8427;
   BB := 33;
   CC := 1440.0;
   DD := AA+BB/CC;
   EE := 8427+33/1440.0;
   WRITELN ( 'DD =' , DD : 20 : 20 ) ;
   WRITELN ( 'EE =' , EE : 20 : 20 ) ;
end.

But they are NOT
DD =8427.022916625000
EE =8427.022460937500

EE is WRONG and can never be considered right.   Why would ANY user with the 
code above expect that the 33/1440 would be done as a single, thus causing a 
loss of precision. 

Again:
"New behaviour: floating point constants are now considered to be of the lowest 
precision which doesn't cause data loss"

This was NOT done in the lowest precision which doesn't cause data loss.. we 
lost data   We are no longer Extended precision, anything at all we use EE 
for is WRONG.

This is CLEARLY WRONG!  The default should be the old way and if you don't like 
the Delphi warnings, you can make a switch to do it this new stupider and WRONG 
way.

I strongly feel this should be reverted, it's just wrong.   This makes no sense 
to me at all.   It's wrong to need to add a compiler directive to do things as 
they are expected by the vast majority to be, the directive should be needed 
for those few who even noticed the warnings in Delphi, and they were just 
warnings, not a substantial reduction in precision. 

James

>But not at the price of loss in precision ! Unless an explicit compiler switch 
>like --fast-math is passed 


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
Hi Jonas, 
That’s Interesting,  Thank you very much for the links!! Not only an 
explanation but a solution. 
The original is how I would expect it to work,  If it's for Delphi 
compatibility why not only do that when in Mode Delphi?   If not in mode Delphi 
who cares if it's compatible?
Delphi is completely wrong to do it this way.
I'm glad there is  $EXCESSPRECISION   I am Immediately putting that in every 
single program I have, because that is I always thought it would work, and I do 
have divisions where this can be a problem.

James
-Original Message-
From: fpc-pascal  On Behalf Of Jonas 
Maebe via fpc-pascal
Sent: Sunday, February 4, 2024 7:21 AM
To: fpc-pascal@lists.freepascal.org
Cc: Jonas Maebe 
Subject: Re: [fpc-pascal] Floating point question

On 03/02/2024 18:42, James Richters via fpc-pascal wrote:
> Constants are also evaluated wrong,you don’t know what that constant 
> is going to be used for, so all steps of evaluating a constant MUST be 
> done in extended by the compiler, or the answer is just wrong.

See
https://wiki.freepascal.org/User_Changes_2.2.0#Floating_point_constants
and https://www.freepascal.org/daily/doc/prog/progsu19.html


Jonas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org 
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Floating point question

2024-02-04 Thread James Richters via fpc-pascal
 in extended and only the final answer be reduced to fit into a smaller 
variable. 
If this was the case, then the result of ALL would be 8427.0229…   
This may be debatable, but certainly when the result is to be stored in a 
double then all operations calculated by the compiler should also be stored in 
doubles, I don't see how anything else could be argued to be correct.
This is not the case at all, or DD, EE, FF, and GG would all be 8427.0229…  but 
only  FF is because I explicitly stated the result of the division is to be a 
double.
 
When the program executes and does math, in the example of BB and CC, and II, 
it’s always correct, but when the compiler evaluates it, it’s doing it wrong. 
And storing portions of the calculation in a single even if the final result is 
a double. 
The compiler should ALWAYS use the highest precision possible, because it can 
be stored in reduce precision variables, but once it’s been butchered by low 
precision, it can’t be fixed. 
 
Constants are also evaluated wrong,  you don’t know what that constant is going 
to be used for, so all steps of evaluating a constant MUST be done in extended 
by the compiler, or the answer is just wrong. 
TT_Const and SS_Const should have been the same, so that when assigned to 
double variables TT_Double and SS_Double they would also be the same.   
TT_Double and TT_Const are wrong.
 
I think this is a legitimate bug you have discovered.  I shouldn’t have to cast 
the division, it’s not what any user would expect to need to do. 
 
My tests were done on a Windows 10 64 bit machine with FPC Win32.
■ Free Pascal IDE Version 1.0.12 [2023/06/26]
■ Compiler Version 3.3.1-12875-gadf843196a


James
 
-Original Message-
From: fpc-pascal  On Behalf Of Thomas 
Kurz via fpc-pascal
Sent: Friday, February 2, 2024 4:37 PM
To: FPC-Pascal users discussions 
Cc: Thomas Kurz 
Subject: Re: [fpc-pascal] Floating point question
 
Well, 8427.0229, that's what I want.
 
But what I get is 8427.0224
 
And that's what I don't unterstand.
 
 
 
- Original Message -
From: Bernd Oppolzer via fpc-pascal < <mailto:fpc-pascal@lists.freepascal.org> 
fpc-pascal@lists.freepascal.org>
To: Bart via fpc-pascal < <mailto:fpc-pascal@lists.freepascal.org> 
fpc-pascal@lists.freepascal.org>
Sent: Sunday, January 28, 2024, 10:13:07
Subject: [fpc-pascal] Floating point question
 
To simplify the problem further:
 
the addition of 12 /24.0 and the subtraction of 0.5 should be removed, IMO, 
because both can be done with floats without loss of precision (0.5 can be 
represented exactly in float).
 
So the problem can be reproduced IMO with this small Pascal program:
 
program TESTDBL1 ;
 
var TT : REAL ;
 
begin (* HAUPTPROGRAMM *)
   TT := 8427 + 33 / 1440.0 ;
   WRITELN ( 'tt=' , TT : 20 : 20 ) ;
end (* HAUPTPROGRAMM *) .
 
With my compiler, REAL is always DOUBLE, and the computation is carried out by 
a P-Code interpreter (or call it just-in-time compiler - much like Java), which 
is written in C.
 
The result is:
 
tt=8427.022916667879
 
and it is the same, no matter if I use this simplified computation or the 
original
 
tt := (8427 - 0.5) + (12 / 24.0) + (33 / 1440.0);
 
My value is between the two other values:
 
tt=8427.022916668000
tt=8427.022916667879
ee=8427.022916625000
 
The problem now is:
 
the printout of my value suggest an accuracy which in fact is not there, 
because with double, you can trust only the first 16 decimal digits ... after 
that, all is speculative a.k.a. wrong. That's why FPC IMO rounds at this place, 
prints the 8, and then only zeroes.
 
The extended format internally has more hex digits and therefore can reliably 
show more decimal digits.
But the last two are wrong, too (the exact value is 6... period).
 
HTH,
kind regards
 
Bernd
 
 
 
Am 27.01.2024 um 22:53 schrieb Bart via fpc-pascal:
> On Sat, Jan 27, 2024 at 6:23 PM Thomas Kurz via fpc-pascal 
> < <mailto:fpc-pascal@lists.freepascal.org> fpc-pascal@lists.freepascal.org>  
> wrote:
 
>> Hmmm... I don't think I can understand that. If the precision of "double" 
>> were that bad, it wouldn't be possible to store dates up to a precision of 
>> milliseconds in a TDateTime. I have a discrepancy of 40 seconds here.
> Consider the following simplified program:
> 
> var
>tt: double;
>ee: extended;
 
> begin
>tt := (8427 - Double(0.5)) + (12/ Double(24.0)) +
> (33/Double(1440.0)) + (0/Double(86400.0));
>ee := (8427 - Extended(0.5)) + (12/ Extended(24.0)) +
> (33/Extended(1440.0)) + (0/Extended(86400.0));
>writeln('tt=',tt:20:20);
>writeln('ee=',ee:20:20);
> end.
> ===
 
> Now see what it outputs:
 
> C:\Users\Bart\LazarusProjecten\ConsoleProjecten>fpc test.pas Free 
> Pascal Compiler version 3.2.2 [2021/05/15] for i386 ...
 
> C:\Users\Bart\LazarusProjecten\ConsoleProjecten>test
&g

Re: [fpc-pascal] What's in Hello World

2024-01-07 Thread James Richters via fpc-pascal
>Try building with smartlinking, -XX

I never knew there was an option for smartlinking.   I'm using the FPC text
IDE, I see various options like 
Generate Smaller Code, and level 1, 2, and 3 optimizations, but I don't see
anything specifically called smartlinking. 
Is it the same as Generate Smaller Code?  or if not, is there another way to
turn it on in the textmode IDE?

James


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Profiling in windows

2024-01-03 Thread James Richters via fpc-pascal
I have a freepascal project for Windows that works really well, but as soon
as I start it, I have high CPU usage, and it stays high, it constantly uses
10% CPU 
while my program is running, even when it's idle waiting for me to make a
selection from its menu.  
 
The main program loop does a few minor things like update the time on the
screen, checks some timers, checks for a keypress, then sleeps until it's
time to do the loop again.
I'm wondering if its getting stuck in some inefficient routine that's
causing all this processor activity.
 
This program only runs under Windows so I'm trying to get a profiler to work
with a windows program.  I came across FPProfiler:
https://wiki.freepascal.org/FPProfiler
 
I'm trying to figure out how it's supposed to work but I haven't made it
very far.  The instructions say to use Lazarus to build the following:
 
.\fpp\fpp.lpi
.\fpp\fppinsert.lpi
.\fpp\fppremove.lpi
.\fppview\fppview.lpi
 
But only .\fpp\fpp.lpi and .\fppview\fppview.lpi  exist, so I compiled those
with Lazarus.
 
I am using the repository at:
http://github.com/graemeg/fpprofiler
 
The svn link doesn't work for me:
http://svn.freepascal.org/cgi-bin/viewvc.cgi/fpprofiler/?root=fpcprojects
 
Also, the instructions say," to compile your project, you pass the same
parameters to FPP as you would to FPC."
I don't use FPC from the command line, I use the FPC textmode IDE. Which I
have set up the way I like it years ago.
Is there some way to know what parameters the text mode IDE is using?  Or
What would the command line be to compile the same way as the IDE?
 
Any advice on how to get this to work, or recommendations on another way I
can profile my program under Windows is greatly appreciated.
 
James
 
 
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Procedures that work like WRITELN()

2023-12-27 Thread James Richters via fpc-pascal
>Writeln() is special. You cannot duplicate it.
That's good to know, I can stop trying.

>What you can do is use WriteStr(), it has the same action as Writeln() but
writes to a string instead of a file.

I was hoping to just replace all existing Writeln()s with my procedure with
a global search and replace.
I think it's probably easiest to make my procedure:

Procedure WriteLog(Filename:String, WriteString:String);
Begin
Writeln(Filename,WriteString);
Writeln(WriteString);
End;

Then just fix the call to concatenate everything into a single string:

So if I end up with this:
WriteLog(Myfile,'some text ',MyInteger);

I'll have to change it to this:
WriteLog(Myfile,'some text '+InttoStr(MyInteger));

And if the arguments are really complicated I can just use WriteStr() to
store it into a string and call my procedure with the resulting string.

It will be a little more effort than doing a global search and replace but
at least I know that it's the only way.

Thanks for the help

James



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Procedures that work like WRITELN()

2023-12-27 Thread James Richters via fpc-pascal
I wanted to write what I thought should be a simple procedure, just instead
of calling WRITELN() with some arguments,
call WRITELOG() with the same arguments that you would use to write to a
file, but my WRITELOG() procedure would 
write to the screen and the file.. but I can't figure out how to pass all
the arguments to the two WRTIELNs.
 
So..
 
Procedure WriteLog(Filename:String, AllOtherAurguments:);
Begin
Writeln(Filename,AllOtherAurguments);
Writeln(AllOtherAurguments);
End;
 
How can I make this work?  Since WRITELN can take any number of many kinds
of arguments,
how can I get them all and pass them along without knowing how many or what
types they are?
How does WRITELN even work when you don't know this information?  
 
I'm guessing there should be some way to do this, because WRITELN itself
works, but how it could 
possibly work is not within my experience. 
 
The only way I could think of would be if there were versions of WRITELN
with every combination
of possible arguments, but that seems completely unmanageable and
ridiculous,
so there must be something more advanced going on, but maybe WRTELN is
special and not something I can duplicate?
 
 
Any Ideas?
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Strings greater than 255 characters

2023-12-19 Thread James Richters via fpc-pascal
>3) There are some other smaller differences impacting compatibility with
code designed to work with type shortstring (e.g. related to used character
sets etc.).

Here's a difference I discovered... 

I see that if I try to do something like:
If MyString[1]='~' Then  ...

If MyString is an AnsiString that is empty then you get a rangecheck error,
which is understandable as there is nothing in character 1, but
If MyString is just a String and is empty then it runs just fine so I
have a lot of those kinds of things.
So some of these I just changed them back to a string for now, but
If I want to change them anyway then I just do 
If  (Length(MyString)>0) and (MyString[1]='~') Then  ...

And that fixes the issue as well, and it's probably better code as I
shouldn't be testing a particular character if there isn't a character
there.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Strings greater than 255 characters

2023-12-19 Thread James Richters via fpc-pascal
I keep getting bit by using STRING variables then trying to store more than
255 characters.  
My typical way to fix this is to just change it to an ANSISTRING.
 
I'm wondering if there is any reason not to do this the other way around and
just go through
My entire program and replace all the STRING variables with ANSISTRNG?  It's
likely that 
I would solve a lot of future problems that I don't even know I have yet if
I did this. 
Is there any reason not to change all the Strings to Ansistrings?
 
I did notice that I cannot have a file of Ansistrings. 
 
Myfile : File of Ansistring;  
Causes a compiler error:
Error: Typed files cannot contain reference-counted types.   
 
So maybe this could be a problem.  Is there a way to make a file of strings
that are not limited to 255 characters?
 
Also I can make records that contain Ansistrings, but I can't make files of
those records, for the same reason as above.
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] case statement

2023-12-14 Thread James Richters via fpc-pascal
I have occasionally had ambiguity with ELSE, for example when you have IF
statements nested inside other IF statements, 
sometimes the ELSE is seen as part of the inner, not the outer, or vice
versa, depending on where the one-liners are
but I just resolve it with some BEGIN - END Blocks, even if they are not
actually needed because there is only one line,  ambiguity resolved. 

For years I have just been in the habit of always putting BEGIN and END on
all IF and ELSE statements, as well as all entries of
CASE statements, whether needed or not,  just because it's so much easier to
stick in some temporary diagnostic code if needed,
it's easier to just always have them and not have to add them later if you
want to do a second thing, which always seems to be happening. 
I guess that's why I never noticed there could be an issue with CASE
statements.

It is handy to know about OTHERWISE though, I'll probably throw it in just
to help remind me that this belongs to the CASE
Statement, and not part of some IF, maybe it will be more readable that way.

James


-Original Message-
From: fpc-pascal  On Behalf Of
Martin Wynne via fpc-pascal
Sent: Thursday, December 14, 2023 3:16 PM
To: fpc-pascal@lists.freepascal.org
Cc: Martin Wynne 
Subject: Re: [fpc-pascal] case statement

I've been using ELSE in IF statements and in CASE statements for 25 years
without realising there was a problem. What a dim-wit I have been.

Martin.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] case statement

2023-12-14 Thread James Richters via fpc-pascal
I didn’t know there was such a thing as OTHERWISE.  Is there any functional 
difference between OTHERWISE and ELSE?

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsoft SAPI on Freepascal

2023-06-27 Thread James Richters via fpc-pascal
I changed to Compiler Version 3.3.1-12875-gadf843196a which is what
FPCUPDeluxe installed when I installed Trunk and now it runs just fine.  
So I guess there was a bug in 3.3.1-10077-gc8403ad49e that was fixed
already.   I was so convinced that I was doing something wrong I didn't even
think to try another version.


>Because I use a screen reader, I have multiple sapi voices installed,
(though I rarely use them), but I haven't played with the code enough just
yet to see why it fails when it tries to select one, when not selecting one
works just fine 

Here's a sample program that now works on the updated 3.3.1, I guess it
should work on 3.2 as well.   It lists all available voices and lets you
choose one.  Maybe that would let you select another voice?

{$Mode OBJFPC}
program VoiceSelection;
uses
  ComObj;

var
  v: OleVariant;
  selectedVoiceIndex: Integer;
  voiceName: string;
  speechText: string;

begin
  v := CreateOleObject('SAPI.SpVoice');

  Writeln('Available Voices:');
  for selectedVoiceIndex := 0 to v.GetVoices.Count - 1 do
  begin
voiceName := v.GetVoices.Item(selectedVoiceIndex).GetDescription;
Writeln('Voice ', selectedVoiceIndex + 1, ': ', voiceName);
  end;

  Writeln;
  Writeln('Enter the index of the voice you want to use:');
  Readln(selectedVoiceIndex);

  if (selectedVoiceIndex < 1) or (selectedVoiceIndex > v.GetVoices.Count)
then
  begin
Writeln('Invalid voice index.');
Exit;
  end;

  voiceName := v.GetVoices.Item(selectedVoiceIndex - 1).GetDescription;
  v.Voice := v.GetVoices.Item(selectedVoiceIndex - 1);
  Writeln('Selected Voice: ', voiceName);
  speechText := 'Hello World, this is ' + voiceName;
  Writeln('Speech Text: ', speechText);
  v.Speak(speechText);
end.




James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsoft SAPI on Freepascal

2023-06-26 Thread James Richters via fpc-pascal
Well that's worth a lot, it may be indicating a bug in 3.3.1?  I guess I
need to get on the current trunk to see if it's still misbehaving.

James

>Also, for what it's worth, your code works fine on fpc 3.20.


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsoft SAPI on Freepascal

2023-06-26 Thread James Richters via fpc-pascal
I was using OleVarient and Varient.  How can I check to see if CreateOleObject 
was successful?
James
>It sounds like " SpVoice := CreateOleObject('SAPI.SpVoice');" is failing and 
>then SpVoice is nil ?
>May be try with an OleVariant instead of a simple Variant ? (i.e declare var 
>SpVoice: OleVariant; )
 
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsoft SAPI on Freepascal

2023-06-26 Thread James Richters via fpc-pascal
When I run the code below I get:
An unhandled exception occurred at $004143C0:
■ Free Pascal IDE Version 1.0.12 [2022/02/07]
■ Compiler Version 3.3.1-10077-gc8403ad49e
■ GDB Version GNU gdb (GDB) 7.2
Running "i:\programming\sapi.exe "
EOleError: Variant does not reference an automation object
  $004143C0
  $004194DD
  $0040B991
  $0040193B  SPEAK,  line 13 of i:/programmingl/sapi.pas
  $00401962  main,  line 17 of i:/programming/sapi.pas

program voice;
uses
comobj;

procedure speak(s : string);

var
v : olevariant;

begin
v:=CreateOleObject('SAPI.SpVoice');
v.Speak(s);
end;

begin
speak('Hello.');
end.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsoft SAPI on Freepascal

2023-06-26 Thread James Richters via fpc-pascal
I appreciate the help with this.  I'm still confused.  
In my original post, I  already had CoInitialize,   CoUninitialize; and Unit
ComOBJ,  Unit Windows and Unit ActiveX I was still getting EOleError:
Variant does not reference an automation object.   

Do I need to do all this Change FPU stuff?

I'm sure I'm doing something wrong but I still can't get it to work. Here's
my original program.  I wasn't even trying to change the voice yet.  What do
I need to do to this to make it work?

James

{$mode objfpc}

uses
CRT, Windows, SysUtils, ComObj, Variants, OLEServer,  Classes,  ActiveX,
ShellApi;

var
  SavedCW: Word;
  SpVoice: Variant;
  MyWideString: WideString;
begin
  CoInitialize(nil);
  SpVoice := CreateOleObject('SAPI.SpVoice');
  MyWideString := WideString('Hello, the time is ' + TimeToStr(Now));
  Writeln(MyWideString);
  // Change FPU interrupt mask to avoid SIGFPE exceptions
  SavedCW := Get8087CW;
  try
Set8087CW(SavedCW or $4);
SpVoice.Speak(MyWideString, 0);
  finally
// Restore FPU mask
Set8087CW(SavedCW);
  end;
  Writeln('Press Any Key');
  ReadKey;
  CoUninitialize;
end.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsoft SAPI on Freepascal

2023-06-26 Thread James Richters via fpc-pascal
I was trying to figure this out on my own.. I went to:
https://wiki.freepascal.org/SAPI

that is where I got my advice.
I took the top example code from the link and made it into the following 
program:

{$Mode OBJFPC}
uses
  comobj;
var
  SavedCW: Word;
  SpVoice: Variant;
begin
  SpVoice := CreateOleObject('SAPI.SpVoice');
  // Change FPU interrupt mask to avoid SIGFPE exceptions
  SavedCW := Get8087CW;
  try
Set8087CW(SavedCW or $4);
SpVoice.Speak('hi', 0);
  finally
// Restore FPU mask
Set8087CW(SavedCW);
  end;
end.

It fails with 

Running "i:\programming\gcode\mill\sapi.exe "
An unhandled exception occurred at $004143F0:
EOleError: Variant does not reference an automation object
  $004143F0
  $0041950D
  $0040B9A1
  $00401931  main,  line 13 of I:/Programming/Gcode/Mill/SAPI.pas

I don't have Lazarus,  just FPC.   I have been going nuts trying to track down 
this unhandled exception.

I tried to make your example into a FPC program without Lazarus:
{$mode objfpc}{$H+}
uses
  comobj;
var
  SavedCW: Word;
  v: OleVariant;
begin
   v:=CreateOleObject('SAPI.SpVoice');
   v.Speak('Hello');
End.
I get:
Running "i:\programming\gcode\mill\sapi.exe "
An unhandled exception occurred at $00414370:
EOleError: Variant does not reference an automation object
  $00414370
  $0041948D
  $0040B941
  $004018DF  main,  line 9 of i:/programming/gcode/mill/sapi.pas

I have tried to trace through with F7  I get a message that "Program generated 
a signal 291... " and then the IDE terminates

I still do not have an example I can compile and run from the FPC IDE (without 
Lazarus)

>I don't know what people advised you, but what you want to do needs 3 lines of 
>code only:

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsoft SAPI on Freepascal

2023-06-26 Thread James Richters via fpc-pascal
I gave up on doing it directly, it seems SO convoluted to do with FPC with the 
COM unit and all this stuff I just don’t understand, 
and it’s SO simple to do with a VBS script in just 3 lines and it just works!  
(it would only be 2 lines if I didn’t want Microsoft Zira)
 
So I decided to do this in the most ridiculous way possible.. but after 3 days 
of trying to get send something directly to SAPI with FPC ,
I’m done with it, and getting this to work was super easy. 
 
Computers are fast enough that I don’t need to waste my time tying to figure 
this out, just have FPC write out a VBS script, and run it with Process.Execute 
problem solved!
 
Here it is, maybe it will help someone else struggling to get something so 
simple to work:
 
{$mode objfpc}
Program Zira;
 
Uses
   SysUtils, Classes, Process;
 
Procedure Zira(ZiraZtring: AnsiString);
Var
   ScriptText: TStringList;
   Process: TProcess;
Begin
   ScriptText := TStringList.Create;
   ScriptText.Add('Set objVoice = CreateObject("SAPI.SpVoice")');
   ScriptText.Add('Set objVoice.Voice = objVoice.GetVoices().Item(1)');
   ScriptText.Add('objVoice.Speak "' + ZiraZtring + '"');
   ScriptText.SaveToFile('ZiraScript.vbs');
   Process := TProcess.Create(nil);
   Process.Executable := 'WScript.exe';
   Process.Parameters.Add('ZiraScript.vbs');
   Process.Execute;
   Process.WaitOnExit;
   ScriptText.Free;
   DeleteFile('ZiraScript.vbs');
End;
 
Begin
   Zira('Hello World');
End.


 
From: fpc-pascal  On Behalf Of Rafael 
Picanço via fpc-pascal
Sent: Sunday, June 25, 2023 2:17 PM
To: fpc-pascal@lists.freepascal.org
Cc: Rafael Picanço 
Subject: Re: [fpc-pascal] Microsoft SAPI on Freepascal
 
Hi James,
 
I am not familiar with variants and Ole objects, sorry about that. I found some 
people using code with Ole objects and it that seems to work, can you chack if 
it applies to your case?
 
https://stackoverflow.com/questions/17970573/using-word-ole-in-lazarus-freepascal
 
Best,
R
 
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsoft SAPI on Freepascal

2023-06-25 Thread James Richters via fpc-pascal
So it’s broken?  It seems like the link you provided is trying to show a 
workaround, but I don’t know how I could apply that.
 
>"Remark Dispatch interface support for variants is currently broken in the 
>compiler." (https://www.freepascal.org/docs-html/ref/refsu20.html)


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Microsoft SAPI on Freepascal

2023-06-25 Thread James Richters via fpc-pascal
Ooops forgot the link:
https://wiki.lazarus.freepascal.org/SAPI
 
From: fpc-pascal  On Behalf Of
James Richters via fpc-pascal
Sent: Sunday, June 25, 2023 8:52 AM
To: 'FPC-Pascal users discussions' 
Cc: James Richters 
Subject: [fpc-pascal] Microsoft SAPI on Freepascal
 
I am trying to get Microsoft speech synthesis to work with Freepascal.  I am
trying to follow the guide here:
 
 
I don't know what I am doing wrong.  SAPI is working on my system, because
the TTSApp Demo that comes with the 
Microsoft Speech SDK works fine.
 
Here is my test program:
 
{$mode objfpc}
 
uses
CRT, Windows, SysUtils, ComObj, Variants, OLEServer,  Classes,  ActiveX,
ShellApi;
 
var
  SavedCW: Word;
  SpVoice: Variant;
  MyWideString: WideString;
begin
  CoInitialize(nil);
  SpVoice := CreateOleObject('SAPI.SpVoice');
  // Change FPU interrupt mask to avoid SIGFPE exceptions
  MyWideString := WideString('Hello, the time is ' + TimeToStr(Now));
  Writeln(MyWideString);
  SavedCW := Get8087CW;
  try
Set8087CW(SavedCW or $4);
SpVoice.Speak(MyWideString, 0);
  finally
// Restore FPU mask
Set8087CW(SavedCW);
  end;
  Writeln('Press Any Key');
  ReadKey;
  CoUninitialize;
end.
 
Whenever my program gets to:
SpVoice.Speak(MyWideString, 0);
 
Even if I hardcode something like:
SpVoice.Speak('Hello', 0);
 
I always get:
Running "i:\programming\TTS.exe "
Hello, the time is 8:41:27
An unhandled exception occurred at $0041FC90:
EOleError: Variant does not reference an automation object
  $0041FC90
  $00424DAD
  $0040BB31
  $00401A8A  main,  line 21 of i:\programming\TTS.pas
 
I don't really understand what this means, and I can't find a complete
sample program that I can just compile and run.   I feel I must be missing
something but I don't know what it is.
 
Any help is greatly appreciated!
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Microsoft SAPI on Freepascal

2023-06-25 Thread James Richters via fpc-pascal
I am trying to get Microsoft speech synthesis to work with Freepascal.  I am
trying to follow the guide here:
 
 
I don't know what I am doing wrong.  SAPI is working on my system, because
the TTSApp Demo that comes with the 
Microsoft Speech SDK works fine.
 
Here is my test program:
 
{$mode objfpc}
 
uses
CRT, Windows, SysUtils, ComObj, Variants, OLEServer,  Classes,  ActiveX,
ShellApi;
 
var
  SavedCW: Word;
  SpVoice: Variant;
  MyWideString: WideString;
begin
  CoInitialize(nil);
  SpVoice := CreateOleObject('SAPI.SpVoice');
  // Change FPU interrupt mask to avoid SIGFPE exceptions
  MyWideString := WideString('Hello, the time is ' + TimeToStr(Now));
  Writeln(MyWideString);
  SavedCW := Get8087CW;
  try
Set8087CW(SavedCW or $4);
SpVoice.Speak(MyWideString, 0);
  finally
// Restore FPU mask
Set8087CW(SavedCW);
  end;
  Writeln('Press Any Key');
  ReadKey;
  CoUninitialize;
end.
 
Whenever my program gets to:
SpVoice.Speak(MyWideString, 0);
 
Even if I hardcode something like:
SpVoice.Speak('Hello', 0);
 
I always get:
Running "i:\programming\TTS.exe "
Hello, the time is 8:41:27
An unhandled exception occurred at $0041FC90:
EOleError: Variant does not reference an automation object
  $0041FC90
  $00424DAD
  $0040BB31
  $00401A8A  main,  line 21 of i:\programming\TTS.pas
 
I don't really understand what this means, and I can't find a complete
sample program that I can just compile and run.   I feel I must be missing
something but I don't know what it is.
 
Any help is greatly appreciated!
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Size of set.

2023-05-23 Thread James Richters via fpc-pascal
>You can transverse a set with
> for ... in

Interesting, I learned something new, I did now know I could do this with 
FreePascal.  It says it works for Strings and Arrays as well, does it also work 
for StringLists?

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Windows Display Settings

2023-05-13 Thread James Richters via fpc-pascal
Is there some way with FreePascal that I can Get / Set  the windows display
settings for multiple monitors like their resolutions, portrait/landscape,
scale factors, and if they are disconnected or not?
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pause Key

2023-04-16 Thread James Richters via fpc-pascal
It occurs to me that since Pause is independent of keypressed,  I could 
actually us it as an extra modifier key if I wanted to... 
"Pause-A" could be different than "A", and also different than "CRTL-A" or 
"ALT-A",  in fact I could do "Pause-CTRL-ALT-A" and have that be different than 
"CTRL-ALT-A"

I could have all kinds of secret command key combinations and no one would ever 
discover them because almost nobody ever pushes the pause key anymore, and even 
if they do, even fewer people would ever uses it as a modifier.

Fun!

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pause Key

2023-04-14 Thread James Richters via fpc-pascal
>> ... I wouldn't be surprised that James's program is a console one, not
using TForm nor any windows message loop to process WM_ messages, but I may
be wrong.

Indeed you are correct, it is a very extensive console application which
uses PTCGraph.   I do accept keyboard input on both the Console window and
the PTCGraph window.  I have a keytest function that I can run in my
application that reports the returned keycodes every time a key is pressed
in either window, but pushing the Pause key is the same as doing nothing, it
does not trigger keypressed.  

However I was already  doing:
isShiftDown := GetAsyncKeyState(VK_Shift);   
because I want to know if shift was held down, I can't rely on just if I get
a capital or lower case letter because caps lock might be on, and I want my
key command to work the same regardless of caps lock. 

So I just added a new function that does:
isPausePushed := GetAsyncKeyState(VK_PAUSE);

and check the pause key every time I check for keypressed  (instead of
inside keypressed) and if it finds it, it executes my Pause routine. 

It's working GREAT!  So Thank you for the help getting it to work in my
console program!

Pause is Back!!  Now I can use F12 for something more useful.

James


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Pause Key

2023-04-13 Thread James Richters via fpc-pascal
Does anyone know what's up with the Pause key in Windows?   
Is there some way to tell if it was pushed?
I have a need for the user to pause execution of my Freepascal program, I
have a pause key.. seems like there should be some way to use it.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Save and Restore Windows 10 Display configuration?

2023-04-03 Thread James Richters via fpc-pascal
Is there some way I can programmatically use FreePascal to save and Restore
all the settings found in the Windows 10  Display settings such as the
resolution and position of each monitor and if they are enabled or not?



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] For Loop with QWord

2023-01-03 Thread James Richters via fpc-pascal
I'm wondering why I can't have the following:
Var
  I: QWord;
Begin
  For I := 1 To N Do
 .
 
It generates an error:
Error: Ordinal expression expected
 
If I change it to LongInt, then it works, but the question is, why can't I
use a Qword here if I know I will never need I to be a negative number?
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Working on a new way to educate people about pascal

2022-12-30 Thread James Richters via fpc-pascal
I don’t know how my previous message got so out of sequence.  I am not 
intending to continue this discussion, it was a message I sent early Thursday 
morning that was somehow delayed and is out of sequence.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Working on a new way to educate people about pascal

2022-12-30 Thread James Richters via fpc-pascal
>Assuming people in that sentence, you are referring to people who use write 
>programs or scripts which make use of databases, if you know very little about 
>the subject of databases on that subject, how can you justify this assertion?
 
The ‘People’ I was referring to are any people who work with databases in any 
way… when you go to the store to return something without a receipt,  the 
customer assistance representative looks up your order on some kind of database 
system that stores all the transactions and is somehow able to retrieve yours 
without knowing SQL.. they are using the database, but know nothing of how it 
work and would never know what SQL was.



>I suggest you either brush up on these subjects or refrain from scolding 
>people on subjects with which you have no practical experience.
 
I apologize if you feel I was scolding you, that was not my intention.  I 
thought we were just having a discussion about it.  You can’t understand why 
anyone would say this is a complicated subject and I was simply trying to 
somehow show you a point of view that you do not seem to understand.  My lack 
of experience is what qualifies me to evaluate your material better than you, 
because if I was familiar with the subject, I would fall into the same trap… 
“well this is just obvious, everyone should follow this.”   I was under the 
impression that you wanted honest feedback, and that’s what I have been trying 
to provide, and I am very sorry if I have offended you.   
 
As a software developer, I have learned from experience, that I am the absolute 
WORST person to test my own programs.  
 
Why is that? 
 
It’s because I wrote them, I know what they are supposed to do and what input 
to give them to get the desired result.  I have no possible way to truly forget 
what I have put in there, and so I am not capable of trying to do it in a way 
someone else might try to do it.
 
When I make a release to my beta testers, it’s normal that they will try to do 
things THEIR way and often they will not understand why the sequence they tried 
didn’t yield the expected result.   At this point, I could do a few different 
things, I can just explain to my beta testers why it didn’t work the way they 
wanted it to, and show them what would have worked.  That is not an ideal 
approach, because if my testers wanted to make it work that way, then maybe ALL 
of my customers also want it to work that way, or maybe 10% of them want it to 
work that way.  A much better solution is to listen to my testers and learn 
from them, and create a program that works in the way that was intuitive to 
THEM, not me.   The best solution would be to get it to work the way I 
originally wanted it to work and also the way they tried to test it at the same 
time, then all of my customers would get the expected results
 
So when I get feedback from my beta testers, I do not get defensive and justify 
why I did it the way that I did.  I don’t try to teach them the way they should 
have done it.  I listen to their extremely valuable feedback and try to 
incorporate that feedback into the product.  They are giving me a point of view 
that I cannot ever possibly have, because when it comes down to it, I can’t 
ever think the way they do.  It’s only through communicating with my testers 
that I can ever see that other point of view.  This other point of view is SO 
valuable, that I have trashed months of work on a project and re-wrote entire 
huge sections to make fundamental changes so that it would work the way someone 
other than myself might want to accomplish something.
 
I was simply trying to offer you that other point of view.   Again, I am very 
sorry if I offended you.
 
James
 
 
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Working on a new way to educate people about pascal

2022-12-29 Thread James Richters via fpc-pascal
>Well, this discussion has not gone well at all!
I agree
 
>I suggest that everyone relax and discontinue pursuing it. 
I apologize to Anthony and everyone on the list for getting too carried away.
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Working on a new way to educate people about pascal

2022-12-29 Thread James Richters via fpc-pascal
nly database I ever use is the one that 
is built into QuickBooks so I can do my accounting, I know my invoices are 
stored in some kind of database, but I really don't care how it works or how to 
manipulate it.. that's what I pay QuickBooks to do. I have absolutely no need 
or time or desire to learn anything about creating or maintaining my own 
database, so the subject just doesn't apply to me.  

To you, these SQL databases are simple and obvious, but that's the problem.. 
you are seeing things from YOUR point of view... not your READER's point of 
view.   To the average reader of your stated target audience, the subject is 
too complicated.  I actually don't even fit into your target audience at all 
because I am very familiar with writing computer software... just not involving 
databases, and I am extremely familiar with Pascal and Free Pascal... yet I 
found it confusing and too complicated.

James



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Working on a new way to educate people about pascal

2022-12-29 Thread James Richters via fpc-pascal
“James, when you raised these questions are you saying that you don't know, or 
that someone who doesn't know much if anything about programming doesn't know”
 
The point I was trying to make is that most of this is gobbely gook to me.   So 
I went looking for something I could recognize.. and I saw a reference to a 
timer, but the only thing we know about it from the article is that there is a 
timer and it needs to get closed, and that TSqlForm.CloseTimerTimer closes it, 
and that is IT.  We don’t know how it got started, how much time it was for, 
why it needs to close, or why in fact there is a timer at all… the reason I 
brought up the timer is because it was the only thing I could really see that 
an average person would recognize as maybe being useful in their own lives.   
 
Anyone who could understand what SQL was from the link you provided or 
understand what the program is even supposed to do, really doesn’t need an 
introduction to Pascal.  I’m not trying to say that the idea itself is bad, in 
fact I do like the way you have links that show specific lines to help with the 
explanation.  I’m just saying, the sample program needs to be on a MUCH simpler 
subject.. something that an average person who is not a computer scientist can 
understand.  A subject that a middle school student could understand and see 
the value of.  I went way beyond what your potential readers would ever do, and 
went to Wikipedia to see what SQL was and I even tried to follow some of the 
code and unfortunately I just couldn’t follow any of it at all.   It seems to 
be just pieces of programs but the reader can’t understand how they relate to 
each other or how it all works.. it’s too complicated.   It really needs to be 
just a single program that starts with does something understandable, that the 
reader could easily copy and paste and play with and understand, not a bunch a 
pieces of code that the reader can’t figure out how these separate pieces 
relate to each other.  That is why Michael mentioned having a Pas2js compiler 
on the page.. it would allow the user to play with the code right there.. but 
this is impossible with your SQL monitor because on a web page there would be 
no server to monitor, and even if they wanted to try this themselves, the would 
have to learn all about SQL to even get started, and that’s never going to 
happen.  So the only interest you will get at all are people who already have 
some SQL thingie that want to monitor it… but even so, they don’t have enough 
information to duplicate your program.. if they cut every bit of code from your 
page, they would not know where or how to paste it to make a functional program.
 
With such a complicated subject, even someone willing to try to figure it out 
what SQL is and why you need to monitor it,  will click the link to ”Entity 
Framework” and go Woah what is all this?? They going to think “All this Free 
Pascal stuff is really super advanced and beyond anything I could have a use 
for”  and while it is true that Free Pascal is VERY advanced and has a LOT of 
ways to accomplish very complicated tasks fairly easily, it also does not HAVE 
to be complicated at all.  In fact you are missing one of the key fundamental 
philosophies of the Pascal programming language,   which is that “Programs 
should be easily understandable by humans”  The image of “The SQL Monitor 
Example Program” doesn’t mean anything to the average person, and it does not 
mean anything to me as an experienced programmer.. it’s just a bunch of 
gibberish that seems to accomplish nothing.  I don’t know why I would ever want 
to monitor that stuff and  I’m afraid you are going to lose your entire 
audience because the subject is just too complex,  unless the reader can 
understand what the program specifically does and how it does it, they aren’t 
going to be interested. 
 
If instead you had an example of a program that everyone could relate to and 
maybe even use themselves you will capture a lot more interest, and if the 
example is relatively simple and easy to follow, with variables that have no 
abbreviations so it’s as readable as possible, and well commented to make sure 
that everything is clear,  then you might get someone to actually download Free 
Pascal and start typing some code, and it seems to me that would be the goal of 
such an introduction.  That’s why I mentioned the timer.. hey a cool program 
that you set an amount of time, then it counts down and maybe makes a sound 
when it’s done.. well everyone that has ever boiled and egg could see why you 
would want to do that.  Then they could see.. this program has a timer,  this 
is how I set the amount of time, this is how I start it, this is what happens 
when it’s done, this is what displays the time left, etc… it serves a purpose 
they can understand and they can follow exactly what is happening and 
understand the end result.
 
James
 
 
 
 
___
fpc-pascal

Re: [fpc-pascal] Working on a new way to educate people about pascal

2022-12-28 Thread James Richters via fpc-pascal
>i think he meant both...

Yes I meant both, I myself as an experience programmer cannot follow really
any of what is going on at all.. except the button that clears the message
box.  I can't figure out why there is a timer, I can't figure out how you
would change the amount of time being timed, or how to start it or how to
stop it or anything at all other than.. look, there's a timer in here..
wonder what that's for and how does that work?
Maybe a nice simple countdown timer would be a better example.

I looked up SQL on Wikipedia and yea.. that's over my head.. that is a VERY
specific and VERY advanced topic.  It's just not anything that the average
person who isn't already a very technical person or in fact very technical
people who just have no use for it would understand.  I couldn't even
understand the Wikipedia article on it.. it's just way outside my experience
and I have no idea what it's for.. but I know I don't have a use for it.  A
nice simple countdown timer would be something everyone could understand the
purpose of and be able to follow along.

I have done a few Lazarus projects, and I do understand it, but in my
opinion Lazarus is a terrible example of Pascal programming, for one simple
reason... There is never a continuous program anywhere.. it's snippets of
code here and snippets of code there.. it's all over the place.  It makes it
VERY difficult for anyone to follow what the heck is going on if you don't
have the actual IDE right in front of you.   The document itself is a
perfect example of this.. there's a block of code here and a block of code
there, but no way to figure out how anything works together.  So that is why
I said start with a console app that has a bunch of Writeln() commands in
it.. it's easy to follow, and you don't need to go here and go there to
figure out what's going on.   Lazarus and GUI applications are ALL too
advanced as an introduction to Pascal because the GUI interface requires
that you have these snippets of code all over the place.   

-Original Message-
From: fpc-pascal  On Behalf Of
wkitty42--- via fpc-pascal
Sent: Wednesday, December 28, 2022 4:46 AM
To: fpc-pascal@lists.freepascal.org
Cc: wkitt...@windstream.net
Subject: Re: [fpc-pascal] Working on a new way to educate people about
pascal

On 12/27/22 9:37 PM, Anthony Walter via fpc-pascal wrote:
> "I see there's a timer there.. but what starts it? What happens when 
> it times out? How do I set the amount of time? Why is there even a 
> timer at all? I don't know any of this."
> 
> James, when you raised these questions are you saying that you don't 
> know, or that someone who doesn't know much if anything about programming
doesn't know?

i think he meant both... there are times when i see "wall of words" code and
can pick some things out of it but why they are there, what they are used
for, and how they operate are still asked... digging deep in the code may
answer those questions after some circuitous path tracing but it depends on
the code...

like james, i also have like 40-45 years programming experience... 99% of my
stuff is still text mode tools and apps... GUI stuff has just never made
sense to me...

--
  NOTE: No off-list assistance is given without prior approval.
*Please keep mailing list traffic on the list where it belongs!*
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Working on a new way to educate people about pascal

2022-12-27 Thread James Richters via fpc-pascal
>>If the target audience are people that are not yet into programming, I
think the code samples might be a little too difficult ?

I have been programming with Pascal since the days of Turbo Pascal, I have
applications with hundreds of thousands of lines of code, and I also program
C++ and Python, but I honestly don't have a clue what's going on at all with
this introduction.
About the only thing I understood was the explanation of clear.button.click
The SQL monitor program example.. I have no idea what any of that means or
what it might be used for.  I don't know what SQL is, never seen it before,
and don't know why you would want to monitor it.

Threads... Sockets... etc.. those are more advanced topics.  

Introductions should be a Hello World Terminal program with maybe some
colored text... something you can follow line by line and it makes sense
even if you don't know what some unit is doing.
After the Hello World program maybe introduce procedures, and show how
repetitive things could be done with a procedure, 
Then show functions and show how a value could be returned from a function.
The introduction should be basic syntax and logic,  maybe some if then
statements or for loops... something easy to follow and understand what's
going on line by line
Then another hello world program with a message box.
Then maybe a simple form.but threads and sockets... ok.. well I know
what threads and sockets are because I happened to use them... but to a
newbie... YIKES what are those?? and SQL??? What the heck is that anyway?
I'm not talking about a newbie.. I mean.. myself... with over 40 years of
programming experience, mostly with Pascal,  What the heck is it and why
would I need to monitor it?  
So how can I type this program in on my own computer and run it, play with
some things and see what happens?  Where am I going to find an SQL thingie
to monitor??   I don't even know what that is.
It's way too advanced of a subject for an introduction to a programming
language and honestly it doesn't make me want to try to lean it.. it's just
Poof WAY over my head. 

With a hello world program, I can type in in my own computer, change the
text,  change the color.. etc.. I can understand it.. if there's a for loop
or some variables, I can follow the logic of what's happening.
In this example, well lets see.. I see there's a timer there.. but what
starts it?  What happens when it times out?  How do I set the amount of
time? Why is there even a timer at all?  I don't know any of this.
I also could not tell you the purpose of the entire program.. I don't know
what an SQL is, what the things mean in the SQL monitor box or why SQLs
whatever they are might need to be monitored.


James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Program efficiency

2022-11-09 Thread James Richters via fpc-pascal
Sounds to me that if the compiler will probably insert temp variables anyway, 
then I might as well make my own and make it easier to understand later. 
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Program efficiency

2022-11-09 Thread James Richters via fpc-pascal
I was wondering if breaking up large complicated formulas into smaller
sections that use more variables is less efficient than just the large
formula.

In other words.. is

A:=(B+C/D)-E^F;
G:=H*(I+J);
K:=L+M/N;
O:= A+G-K;

Less efficient than
O:= ((B+C/D)-E^F)+ (H*(I+J))-(L+M/N);

Or does it end up being the same when it's done?

I have a tendency to avoid using variables even though the code would be
infinitely more understandable if it was broken into sections and more
variables were used, but I'm wondering if this is really any more efficient
or if it just seems like it should be... after all storing things in a
variable and reading them out should take some time... but then again the
processor only works on one operation at a time anyway, so the final
assembly code would probably have to store things somewhere and get them
back... so.. is it really faster?

So if I never need the value a second time, is it really better to avoid
variables?

I could  break it up an use comments:
O:= ((B+C/D)-E^F)+   //A
   (H*(I+J))- //G
   (L+M/N); //K

This got me thinking, it would be cool if there was some king of utility
that counted clock cycles for you while your program ran..and then I could
just try a sample program both ways and see what the results are...

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] mciSendString with long file names

2022-09-22 Thread James Richters via fpc-pascal
Sorry for the confusion.   Let me clarify:

The freepasal program is always run on a Windows system,  mciSendString is a 
Windows function.  I've seen solutions for this problem that use the NTFS 8.3 
Short file name... Which I thought would work, but, for my application it won't 
work because the file is being loaded off a network drive, and the SERVER for 
the file is a Linux server.. but even though it's a Linux server, the path on 
my windows system is still uses backslashes not forward slashes... It's a 
FreeNAS server with Windows file sharing.  Anyway the point was that only 
windows NTFS formatted drives have the short file name.. so that solution won't 
work at all.  I want the program to be able to play the sound file no matter 
where the file is stored on the network or on a flash drive or a ramdrive.. 
etc,  and not have a requirement that it is an NTFS drive.

So it has to work with windows paths.  Almost all windows applications just put 
it in quotes, but mciSendString does not play nice.  I think it was invented 
during 8.3 limitations and it was only hacked to kind of work with long file 
names.. not really work properly.  The Alias method does work, but it's not so 
convenient for Asynchronous mode because it leaves the file open.. if you close 
it before it finishes playing, it stops and if you wait for it to finish and 
then close it.. well, that's just not asynchronous.

James

-Original Message-
From: fpc-pascal  On Behalf Of Travis 
Siegel via fpc-pascal
Sent: Thursday, September 22, 2022 3:27 PM
To: ja...@productionautomation.net; FPC-Pascal users discussions 

Cc: Travis Siegel ; James Richters 

Subject: Re: [fpc-pascal] mciSendString with long file names

That's on windows, you said the program was running on linux.  In that case, 
backslashes will escape the spaces, allowing the path to be found properly.

Windows paths are different, as mentioned before, they can be escaped too, but 
the character is different.

On 9/22/2022 2:57 PM, James Richters via fpc-pascal wrote:
> Won’t backslashes before each space be defining a subdirectory?
>
> If my path looks like:
> C:\Program Files\My Program\Some File.MP3 I don't see how changing it 
> to:
> C:\Program\ Files\My\ Progam\Some\ File.MP3 can possibly work.. it's just 
> butchering the path.
>
> James
>
>
> From: fpc-pascal  On Behalf 
> Of Travis Siegel via fpc-pascal
> Sent: Wednesday, September 21, 2022 4:15 PM
> To: FPC-Pascal users discussions 
> Cc: Travis Siegel ; Jean SUZINEAU 
> 
> Subject: Re: [fpc-pascal] mciSendString with long file names
>
> Adding a backslash (\) before each space should do the job nicely.  I have 
> had similar issues on linux and windows with some commands, and adding the 
> escape characters to the filename almost always fixes the problem.  The only 
> time it didn't, was when the filename started with a dash "-" character.  
> Otherwise, the backslash always works for me.
>
> On 9/20/2022 4:16 PM, Jean SUZINEAU via fpc-pascal wrote:
> May be by escaping the spaces with ^ ?
> Something like:  MyFileName:= StringReplace(MyFileName, ' ', '^ ', 
> [rfReplaceAll]); ^ is the escape char for cmd.exe but may be it is active in 
> this context too ?
> Le 20/09/2022 à 18:31, James Richters via fpc-pascal a écrit :
> I just tried it that way:
> Var
> pcmd: String;
> MyFileName: String;
>   
> pcmd:='play "'+MyFileName+'"'+#0;
> mciSendString(@pcmd[1],Nil,0,0);
>   
>
>
>
> ___
> fpc-pascal maillist  -  mailto:fpc-pascal@lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>
> ___
> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org 
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org 
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] mciSendString with long file names

2022-09-22 Thread James Richters via fpc-pascal
Won’t backslashes before each space be defining a subdirectory?

If my path looks like:
C:\Program Files\My Program\Some File.MP3 
I don't see how changing it to:
C:\Program\ Files\My\ Progam\Some\ File.MP3 can possibly work.. it's just 
butchering the path.

James


From: fpc-pascal  On Behalf Of Travis 
Siegel via fpc-pascal
Sent: Wednesday, September 21, 2022 4:15 PM
To: FPC-Pascal users discussions 
Cc: Travis Siegel ; Jean SUZINEAU 

Subject: Re: [fpc-pascal] mciSendString with long file names

Adding a backslash (\) before each space should do the job nicely.  I have had 
similar issues on linux and windows with some commands, and adding the escape 
characters to the filename almost always fixes the problem.  The only time it 
didn't, was when the filename started with a dash "-" character.  Otherwise, 
the backslash always works for me.

On 9/20/2022 4:16 PM, Jean SUZINEAU via fpc-pascal wrote:
May be by escaping the spaces with ^ ?
Something like:  MyFileName:= StringReplace(MyFileName, ' ', '^ ', 
[rfReplaceAll]);
^ is the escape char for cmd.exe but may be it is active in this context too ?
Le 20/09/2022 à 18:31, James Richters via fpc-pascal a écrit :
I just tried it that way:
Var 
pcmd: String;
MyFileName: String;
 
pcmd:='play "'+MyFileName+'"'+#0;
mciSendString(@pcmd[1],Nil,0,0);
 



___
fpc-pascal maillist  -  mailto:fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] mciSendString with long file names

2022-09-20 Thread James Richters via fpc-pascal
I ran into a problem just removing spaces for the alias name,  I guess the
slashes and colon from the path are not valid for the alias, 
 so now I have a new function that removes everything that is not a letter,
and that seems to have solved the problem:

mciSendString(PChar(Ansistring('Close '+LettersOnly(MyLongFileName))), Nil,
0, 0);
mciSendString(Pchar(Ansistring('Open ' + #34+MyLongFileName+#34 + ' alias '+
LettersOnly (MyLongFileName))), Nil, 0, 0); 
mciSendString(PChar(Ansistring('Play '+ LettersOnly (MyLongFileName)+'
wait')), Nil, 0, 0);

I'm still trying to see if there is a way to close everything even if I
don't know the alias anymore.

James

-Original Message-
From: fpc-pascal  On Behalf Of
James Richters via fpc-pascal
Sent: Tuesday, September 20, 2022 5:21 PM
To: 'FPC-Pascal users discussions' 
Cc: James Richters ; 'Alexander
Hofmann' 
Subject: Re: [fpc-pascal] mciSendString with long file names

That Alias method does seem to work.. thank you for the suggestion, although
it makes it more complicated for asynchronous operation, which is of course
what I wanted.

So here is what I came up with.. for synchronous operation, this works fine:
mciSendString(Pchar(Ansistring('Open ' + #34+MyLongFileName+#34 + ' alias
myalias wait')), Nil, 0, 0); 
mciSendString(PChar(Ansistring('Play myalias wait')), Nil, 0, 0);
mciSendString(PChar(Ansistring('Close myalias)), Nil, 0, 0);

but without the wait, it closes before it plays.. and I don't want my
application to wait for the sound to finish before moving on, so for
asynchronous operation, I just put the close before the open and it seems to
work, to make sure the alias is available, and it seems to work.  
I also need unique alias names, in case 2 sounds are trying to be played
back to back, otherwise the second one will not be able to use the alias but
that's easy to generate by just removing the spaces from the file name.
This seems to work:

mciSendString(PChar(Ansistring('Close '+Nospaces(MyLongFileName))), Nil, 0,
0);
mciSendString(Pchar(Ansistring('Open ' + #34+MyLongFileName+#34 + ' alias
'+Nospaces(MyLongFileName))), Nil, 0, 0); 
mciSendString(PChar(Ansistring('Play '+Nospaces(MyLongFileName)+' wait')),
Nil, 0, 0);

I suppose I really need to close it at some point after it's done, but by
then my process is long past the procedure that fired it off... at least for
repeat playing, it will have closed the old one before it made a new one.

I wonder if there is a way to do a 'CLOSE ALL' that I could run when before
my program exits just to clean up the system.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] mciSendString with long file names

2022-09-20 Thread James Richters via fpc-pascal
That Alias method does seem to work.. thank you for the suggestion, although it 
makes it more complicated for asynchronous operation, which is of course what I 
wanted.

So here is what I came up with.. for synchronous operation, this works fine:
mciSendString(Pchar(Ansistring('Open ' + #34+MyLongFileName+#34 + ' alias 
myalias wait')), Nil, 0, 0);
mciSendString(PChar(Ansistring('Play myalias wait')), Nil, 0, 0);
mciSendString(PChar(Ansistring('Close myalias)), Nil, 0, 0);

but without the wait, it closes before it plays.. and I don't want my 
application to wait for the sound to finish before moving on, 
so for asynchronous operation, I just put the close before the open and it 
seems to work, to make sure the alias is available, and it seems to work.  
I also need unique alias names, in case 2 sounds are trying to be played back 
to back, otherwise the second one will not be able to use the alias
but that's easy to generate by just removing the spaces from the file name.
This seems to work:

mciSendString(PChar(Ansistring('Close '+Nospaces(MyLongFileName))), Nil, 0, 0);
mciSendString(Pchar(Ansistring('Open ' + #34+MyLongFileName+#34 + ' alias 
'+Nospaces(MyLongFileName))), Nil, 0, 0);
mciSendString(PChar(Ansistring('Play '+Nospaces(MyLongFileName)+' wait')), Nil, 
0, 0);

I suppose I really need to close it at some point after it's done, but by then 
my process is long past the procedure that fired it off... at least for repeat 
playing, it will have closed the old one before it made a new one.

I wonder if there is a way to do a 'CLOSE ALL' that I could run when before my 
program exits just to clean up the system.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] mciSendString with long file names

2022-09-20 Thread James Richters via fpc-pascal
I just figured out that short filenames won't work, my files are on a linux
server... not NTFS drives.. so I'm back to getting it to work with spaces
the normal file names
James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] mciSendString with long file names

2022-09-20 Thread James Richters via fpc-pascal
I just tried it that way:
Var 
pcmd: String;
MyFileName: String;
 
pcmd:='play "'+MyFileName+'"'+#0;
mciSendString(@pcmd[1],Nil,0,0);
 
I get the same results,  files with no spaces in the name even long file
names play fine, if there's spaces, they won't play.
 
I had the idea to just get the windows short file name and pass it on to
play the sound instead of bothering to figure out why spaces won't work.
I found getshortpathname:
https://www.freepascal.org/daily/packages/winunits-jedi/jwawinbase/getshortp
athname.html
 
function GetShortPathName(
  lpszLongPath: LPCTSTR;
  lpszShortPath: LPTSTR;
  cchBuffer: Windows.DWORD
):Windows.DWORD;
 
 
does anyone know how to convert a pascal string to the LPCTSTR needed for
the long path and then how to convert the LPTSTR short path to LPCTSTR for
mciSendString?
 
Are the LPCTSTR and LPTSTR just PChar strings or something else?
 
James
 
>I've only ever done this like:
> 
>pcmd: string;
> 
>pcmd:='open "'+filename+'" ... '+#0;
> 
>mciSendString(@pcmd[1], ...);
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] mciSendString with long file names

2022-09-20 Thread James Richters via fpc-pascal
I'm trying to get mciSendString() to work with long file names with spaces
in them and I'm not having any success.
I know with winnows you need quotes around long file names, so I'm trying
things like this:
 
Var MySoundFile:String;
mciSendString(PChar('play '+Ansistring(#34+MySoundFile+#34)),Nil,0,0);
 
But still it works if my file name has no spaces, but does not work if there
are spaces.
I think maybe it's my conversion to a PChar, but it works as long as there
are no spaces, so I don't know.
 
The name of my file is in a string because it comes from a record with a
string variable in it.. part of another whole system that I don't want to
change just to get this to work.
 
Any one have any ideas how to get long file names with spaces to work?
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] SerReadTimeout question

2022-09-18 Thread James Richters via fpc-pascal
I can't seem to find any documentation or SerRead or SerReadTimeout..
searching for either along with Freepascal doesn't get me any results.  
If it exists somewhere and I am just missing it, can someone tell me where
it is?

Anyway, what I'm trying to figure out is when the timeout timer starts...
does the timeout timer start when I call the funciton, or does it start when
there is no data to read... waiting for a certain amount of time to see if
there is more data?  Of course it will also stop when the requested number
of bytes is satisfied.

I'm trying to read as fast as reliable, but I don't always know how many
bytes I'm expecting.  So it would be handy it the timer started when there
was nothing to read.. then I could have a very small timeout and as long as
data was coming in, I would get it, until the requested number of bytes is
reached... but if the timer stated when I call the function, I will have to
caclculate how long it should take and add a little in case the data isn't
ready when I ask for it.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Getting Shift key with PTCCRT

2022-09-18 Thread James Richters via fpc-pascal
I came up with a solution for this.  Since I am on windows, I found I can
just check GetAsyncKeyState between keypressed and readkey like this:

 If PTCCRT.KeyPressed then
Begin
   isShiftDown := GetAsyncKeyState(VK_Shift);
 MyKey:=PTCCRT.ReadKey;
End;

James


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get highest element of a StringList

2022-09-12 Thread James Richters via fpc-pascal
So I could just do this?

Index:= MyStringlist.IndexOfName(SearchName);
If Index >=0 then
   MyValue := MyStringlist[Index].ValueFromIndex;

That sure is nice to know, Thank you!

I guess for my dynamic arrays of records, I still need to search with a
loop... or is there a cool thing I don't know about for that as well?

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get highest element of a StringList

2022-09-12 Thread James Richters via fpc-pascal
The problem with the for in loop is that I need the index.

I'm sometimes searching through the stringlist looking for a match, and when I 
find a match, I want to read the value
And then do a break, because there is no point is searching once I found what I 
am looking for:

For I:= 0 to MyStringlist.high Do
   Begin
   If MyStringlist[I].Names = SearchName Then
  Begin
MyValue := MyStringlist[I].ValueFromIndex;
Break;
  End;
   End;

I agree that the for - in loop is a great way if you are always processing the 
entire list and don't need the index for anything.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get highest element of a StringList

2022-09-11 Thread James Richters via fpc-pascal
The loops is just an example because in my original post of why I wanted to
get the highest element of a stringlist was because I wanted a for loop that
wasn't as clumsy as

For I:=0 to myStringlist.count-1 Do

This came up because thanks to this discussion list, I learned I could use
High() and Low() for my dynamic arrays,  so I went through replacing all
instances of 

Length(MyDynamicArray)-1 with  High(MyDynamicArray)

So my for loops went from:

For I:=0 to Length(MyDynamicArray)-1 Do 
To 
For I:=0 to High(MyDynamicArray) Do

Which I find much more clear and less prone to problems.. I have forgot the
-1 before and it gives range check errors of course.. so I'm switching
everything to use High() instead and will just automatically use High() in
the future, thus preventing the issue all together.

I'm really happy with the helper function and using MyStringList.High.  I
think .High should just be added to all things that have a .Count because
everyone always needs it ALL THE TIME.  But I am happy it's possible to add
a helper function to add it myself.

James

>Why the loop?

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get highest element of a StringList

2022-09-10 Thread James Richters via fpc-pascal
Thank you for the example! I also needed 

{$Mode OBJFPC}  

to get it working.  I am normally in
{$Mode FPC} Or {$Mode TP}
But I found that if I just put this in a unit that is {$Mode OBJFPC} and
include that unit in my {$Mode TP} Unit it works just great!

I have a useless unit that is just a whole list of constants, types, and
variables used by my other units, just so I don't have to scroll past over
1000 lines of code just to get to the functions and procedures.
It was {$Mode FPC}

For some reason
{$Mode FPC}
{$modeswitch typehelpers}
Still had Error: Identifier not found "class"

So I changed it to 
{$Mode OBJFPC}
{$modeswitch typehelpers}
And put the function in it, and it's working great!

My main reason for wanting something like this is because I occasionally
will forget the -1 and... well... that's no good...
Since I recently learned of High() and Low() for arrays, I've been changing
all my for loops with arrays to use High() and sometimes Low() if they don't
start at 0.  It's also helpful to do something like:

MyArray[High(MyArray)] := something;  

To write to a newly added array element where I used to have

MyArray[Length(MyArray)-1] := something;  

While it does work.. it's less readable and prone to errors.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get highest element of a StringList

2022-09-10 Thread James Richters via fpc-pascal
This Helper sounds like a nice way to do it.  I need the numerical index of
the loop so this would be more straight forward.
Would I then do something like :
For I:= 0 to MyStringList.High Do 
?

When I try to add the Type statement:
type TStringListHelper = class helper for TStringList function High:
NativeInt; end;
I getError: Identifier not found "class"

I have the Classes unit.  Is there something else I am missing?

James

>Another alternative would be declaring a helper:

>type TStringListHelper = class helper for TStringList function High:
NativeInt; end;

>function TStringListHelper.High: NativeInt; begin
>  Exit (Self.Count-1);
>end;

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Get highest element of a StringList

2022-09-10 Thread James Richters via fpc-pascal
I thought I would try:

For Loop := 0 to High(MyStringList) do

But I get "Error: Type mismatch"

Is there a way to get the highest element of a stringlist other than:

For Loop := 0 to MyStringList.Count-1 do

It would be nice to not have the -1
Could High() be made to work if the argument was a stringlist?

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Getting Shift key with PTCCRT

2022-09-10 Thread James Richters via fpc-pascal
Thanks for the suggestion

I think the syntax should be:
type myKeyEvent = IPTCKeyEvent;
Var myShiftStatus : boolean;

myShiftStatus := myKeyEvent.Shift;

but I get IPTCKeyEvent not found.  I wonder if it's only designated as
internal.. or if I need to use something other than PTCGraph and PTCCRT

James
>looking at the list of constants in ptcpas, i find PTCKEY_SHIFT... i also
find, in Classes, the IPTCKeyEvent which has a GetShift function as well as
a Shift 
>property... seems like you should be able to the shift status with
something like

>type myKeyEvent : IPTCKeyEvent;
>type myShiftStatus : boolean;

>myShiftStatus := myKeyEvent.Shift;

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Access Violation When SetLength(DynArray, Value)

2022-09-09 Thread James Richters via fpc-pascal
>With FPC 3.2.0 and newer you can do "Concat(MyArray, [TheNewElement])" or (if 
>modeswitch ArrayOperators is active) "MyArray := MyArray + [TheNewElement]".

I have a lot of arrays of records, but I just build the record into the array 
elements, like this:
  
SetLength(MathArray,Length(MathArray)+1);
  
MathArray[High(MathArray)].Variable:=NewVariable;
  
MathArray[High(MathArray)].Formula:=NewEquation;

Could either of the methods mentioned work directly with something like this or 
would I have to build the record first and do:
MyRecord.Variable:=NewVariable;
MyRecord.Formula:=NewEquation;
MathArray:= MathArray+ MyRecord;


I thought I would make my own IncArray() function:

Procedure IncArray(Var TheArray);
Begin
   SetLength(TheArray,Length(TheArray)+1);
End;

But I get a 'Type Mismatch'  Any ideas how this could be done?  Is this even 
possible without specifying the exact type of array?

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Getting Shift key with PTCCRT

2022-09-09 Thread James Richters via fpc-pascal
I have some key sequences with PTCCRT.READKEY  where I use a lower case
letter to do one thing and an uppercase to do another, but if the Capslock
is on, they do the wrong things.  Is there a way I can check the condition
of the shift key to see if shift was actually pressed instead of just going
by whether I got a capital letter or not?   The key input is not something
that is ever displayed on the screen, it's just making selections and doing
them.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Access Violation When SetLength(DynArray, Value)

2022-09-09 Thread James Richters via fpc-pascal
I only recently learned about using Low() and High() and it is so much nicer
than 
For I:= 0 to Length(MyArray)-1 Do

That I actually went though all my code replacing the Length() - 1's with
High()

I still end up with a lot of 
SetLength(MyArray,Length(MyArray)+1); 
Every time I want to add one more thing to the array.

Almost all of my  dynamic arrays do this, because I can only add one thing
at a time to the array... and the reason I wanted it to be dynamic in the
first place.  

Is there some nifty way to increase a dynamic array by 1 that is more
elegant?  
Inc(MyArray); would sure be nice

James


>To avoid this kind of error you can use
>
>   for i:= 0 to High(Rails) do
>
>or even
>
>for i:= Low(Rails) to High(Rails) do

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] BoolToStr

2022-08-29 Thread James Richters via fpc-pascal
Thanks for the discussion everyone, it does shed some light on what's going on. 
  I agree it would be impossible to change it now, It was actually a GREAT idea 
to make it customizable, and that serves my needs just fine.  
I guess all that's left is to update the documentation to show what it really 
does and show how it is customizable.   I wouldn't mind doing that... if I knew 
how.  What is the proper method to submit documentation change requests?

James  

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] BoolToStr

2022-08-28 Thread James Richters via fpc-pascal
I don't see how it makes anything compatible at all.. because it's NOT a 0 or a 
-1 integer value,  it's a STRING of '0' or '-1' so you can't even evaluate the 
negative bit.. because there isn't one, it's a string of - and 1.   You would 
have to do StrToInt(BoolToStr(MyVariable)) to be able to evaluate the negative 
bit... which again is useless because there is only one bit to check.. indeed 
you would need to do  StrToInt(BoolToStr(MyVariable)) just to evaluate the 0 as 
a numeric value, but then this is a really round about way to do it when you 
could make a simple BoolToInt function to just give you the numeric result.

Even if it is convenient to set the - flag for "All Bits Set"  it doesn't apply 
to BoolToStr, because we aren't evaluating a Nibble, or a Byte, or a Word, etc, 
we are only evaluating a single bit Boolean variable.. so there are no, ALL 
Bits, there is only THE Bit.  I guess technically ALL one of it was set... but 
making it a -1 makes it more difficult to stack a bunch of these bits together 
into a word or something, and the - really serves no purpose if there is only 
one bit.. in fact you can't even put it into a byte because -1 isn't a valid 
Byte.  You would have to do MyByte:=Abs(StrToInt(BoolToStr(True)));

I think it would be best to make BoolToStr always produce 'TRUE' or 'FALSE' as 
the default because that is what is documented, and that is also what makes the 
most sense.. after all you are asking for a STRING, so you are outputting to 
something that wants a String, probably to be readable at some point, if you do 
Writeln of a Boolean you get 'TRUE' or 'FALSE', and BoolToStr should do that 
same thing... just like the documentation indicates.  

An additional BoolToInt could be added that returned an integer, which I think 
should return a 0 or a 1, but maybe retain the ability to customize the integer 
output the same way BoolToStr does, then if you want to check the - flag 
instead of checking the 1 bit, you could do that.. as silly as it is for a 1 
bit test. 

Anyway, I suppose such a change would break a whole pile of stuff at this 
point, so it's probably not going to happen... but it would be nice if it made 
more logical sense, and BoolToInt is what you need if you want to get a 0 and 1 
(or 0 and -1 as the case may be) numerical value, but there doesn't appear to 
be one in FPC.

I'm curious if there is a way to search the FPC version history of changes for 
BoolToStr to see why it was changed, and see if there is a valid reason not to 
change it back. it was obviously changed from the way the documentations is at 
some point.  It really seems to me that if it was that important that someone 
had a function that output a 0 or a -1, the only way it makes sense is if it's 
an integer, not a string. 

If a special function is needed for some COM thing or weird Winapi thing, then 
that function should be part of the unit that needs it, not modifying the 
generic function intended to be used for general purpose applications output 
something that does not conform to other Pascal Boolean datatypes and just 
confuses everyone.

James


Op 8/28/2022 om 8:45 PM schreef Ralf Quint via fpc-pascal:
On 8/28/2022 8:23 AM, James Richters via fpc-pascal wrote:
Running "i:\booltostr.exe " 
-1
0
 
Why true is -1 instead of 1 is beyond me, but anyway, I would consider this 
BoolToInt, not BoolToStr,  I want the Strings ‘TRUE’ or ‘FALSE’ as indicated in 
the documentation
Very logical in fact. 0 is NO bit set in any given size of boolean data type, 
-1 means ALL bits set on that same size boolean data type.  
Pascal boolean datatypes only have 0 or 1 as defined values.  But probably it 
is for some COM or Winapi compatible purpose.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] BoolToStr

2022-08-28 Thread James Richters via fpc-pascal
> You can use

BoolToStr(b,'TRUE','FALSE')

That works great!  Shouldn't that be the default and you can put in
something else if you want it?  It's Boolean To String... not Bool to some
number.  
If I just do Writeln(True);  I get the string 'TRUE' 
The text 'TRUE' is what you get if you convert a Boolean value of 1 to a
string, not anything else.  

I guess the default must have been 'TRUE' or 'FALSE' at one time as that is
how the documentation is written, it must have been changed to be compatible
with Delphi code at some point I guess.

Thanks for the suggestion, it works for my needs.

James.



-Original Message-
From: fpc-pascal  On Behalf Of
Michael Van Canneyt via fpc-pascal
Sent: Sunday, August 28, 2022 11:39 AM
To: ja...@productionautomation.net; FPC-Pascal users discussions

Cc: Michael Van Canneyt ; James Richters

Subject: Re: [fpc-pascal] BoolToStr



On Sun, 28 Aug 2022, James Richters via fpc-pascal wrote:

> I'm generating a report where I wish to display some Boolean values.  
> I thought I would try BoolToStr, as according to:
> https://www.freepascal.org/docs-html/rtl/sysutils/booltostr.html it
states:
>
> Description
> BoolToStr converts the boolean B to one of the strings 'TRUE' or 'FALSE'
>
> So it should do exactly what I want. output the text string 'TRUE' or 
> 'FALSE'  depending on the Boolean state, but that is not what happens:
>
> Uses Sysutils;
> Begin
> Writeln(BooltoStr(True));
> Writeln(BooltoStr(False));
> End.
>
> Running "i:\booltostr.exe "
> -1
> 0
>
> Why true is -1 instead of 1 is beyond me, but anyway, I would consider 
> this BoolToInt, not BoolToStr,  I want the Strings 'TRUE' or 'FALSE' 
> as indicated in the documentation

I will adapt the documentation to be more precies.

You can use

BoolToStr(b,'TRUE','FALSE')

or
BoolToStr(b,True)

in which case it will use the BoolStrs arrays to determine the strings.

-1 and 0 are the Delphi values, which, I agree,  are not very intuitive.

>
> And BoolToInt should always output 0 or 1, not matter what operating 
> system you are on.. I don't understand the -1.  I guess some Windows 
> API's use -1 for true.. I still don't understand.
> Maybe there should be a BoolToBit that could always be 0 or 1 
> regardless of the operating system.

As said, the 0 and -1 are for Delphi compatibility.

Use

Ord(Boolean)

It will give you 0 and 1.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] BoolToStr

2022-08-28 Thread James Richters via fpc-pascal
I'm generating a report where I wish to display some Boolean values.  I
thought I would try BoolToStr, as according to:
https://www.freepascal.org/docs-html/rtl/sysutils/booltostr.html it states:
 
Description
BoolToStr converts the boolean B to one of the strings 'TRUE' or 'FALSE'
 
So it should do exactly what I want. output the text string 'TRUE' or
'FALSE'  depending on the Boolean state, 
but that is not what happens:
 
Uses Sysutils;
Begin
Writeln(BooltoStr(True));
Writeln(BooltoStr(False));
End.
 
Running "i:\booltostr.exe "
-1
0
 
Why true is -1 instead of 1 is beyond me, but anyway, I would consider this
BoolToInt, not BoolToStr,  I want the Strings 'TRUE' or 'FALSE' as indicated
in the documentation
 
And BoolToInt should always output 0 or 1, not matter what operating system
you are on.. I don't understand the -1.  I guess some Windows API's use -1
for true.. I still don't understand.
Maybe there should be a BoolToBit that could always be 0 or 1 regardless of
the operating system.  
 
I know I can write my own simple function to do it the way I want,  but why
does this behavior not match the documentation?
The whole point of having lots of little functions like FloatToStr, is so
everyone doesn't have to keep writing the same functions over and over.
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] FPConnect Timeout

2022-06-08 Thread James Richters via fpc-pascal
I'm not quite following how I could implement that. 

Here is what I am trying to do:
Uses
Serial,Sysutils,Sockets,CRT;
var
  Socket_Address: TSockAddr;
  opt: LongWord;
  Connect_Result : Integer;
  TCP_Connect_Socket : Tsocket;
begin
   Modbus.Device[Device_Number].TCP_Socket := fpsocket(PF_INET, SOCK_STREAM, 
IPPROTO_TCP);
   if Modbus.Device[Device_Number].TCP_Socket = TSocket(INVALID_SOCKET) then
  Writeln('Error Creating Socket: ',SocketError);
   Socket_Address.sin_family := AF_INET;
   Socket_Address.sin_addr := 
StrToNetAddr(Modbus.Device[Device_Number].Connection);
   Socket_Address.sin_port := htons(Modbus.Device[Device_Number].TCP_Port);
   Connect_Result := fpconnect(Modbus.Device[Device_Number].TCP_Socket, 
@Socket_Address, sizeof(Socket_Address));
   if Connect_Result = SOCKET_ERROR then 
  Writeln('Error Connecting Socket: ',SocketError);   // I want to get this 
error in 2 seconds
...

Are you saying to use TInetSocket instead of the Sockets unit?  Or do I just 
figure out how to use set ConnectTimeout and then that's the timeout that will 
be used, and still use everything else the same?

James

-Original Message-
From: fpc-pascal  On Behalf Of 
Dimitrios Chr. Ioannidis via fpc-pascal
Sent: Wednesday, June 8, 2022 1:11 PM
To: fpc-pascal@lists.freepascal.org
Cc: Dimitrios Chr. Ioannidis 
Subject: Re: [fpc-pascal] FPConnect Timeout

Hi,

Στις 8/6/2022 7:27 μ.μ., ο/η James Richters via fpc-pascal έγραψε:
> Is there any way to specify a shorter timeout for FPConnect?

AFAIK, socket connect timeout is implemented in ssockets ( in TSocketStream ) 
not in sockets unit.

You can use the TInetSocket's class from ssockets unit ( this is what 
fphttpclient uses ) overloaded constructor with the aConnectTimeout parameter 
or if you want you can use the ConnectTimeout property before connect and 
you're ready to go ...

regards,

--
Dimitrios Chr. Ioannidis

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org 
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] FPConnect Timeout

2022-06-08 Thread James Richters via fpc-pascal
Is there any way to specify a shorter timeout for FPConnect?


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] PTCGraph window location

2022-03-13 Thread James Richters via fpc-pascal
For my application, I want to put the window where it goes and not allow it to 
be moved.  I am doing:
 
SetWindowLongPTR(graphicwindow, GWL_STYLE, GetWindowLong(graphicwindow, 
GWL_STYLE) AND not(WS_SIZEBOX) And not(WS_Caption));
 
WS_Caption is the title bar
And 
WS_Seizebox is a border around the window that I don’t want either.
 
I could do all this stuff myself easy enough and get the desired result if 
there was just an option to create the PTCGraph window with WS_VISIBLE turned 
off.
I could move it, remove the title, and whatever then make it visible when I’m 
done, and the screen won’t be flickering with all kinds of window movements.
 
I change the title of the existing window without reopening the window with:
SetWindowTextA(graphicwindow,wintitletouse);
 
James
 
 
From: fpc-pascal  On Behalf Of Nikolay 
Nikolov via fpc-pascal
Sent: Saturday, March 12, 2022 10:51 AM
To: fpc-pascal@lists.freepascal.org
Cc: Nikolay Nikolov 
Subject: Re: [fpc-pascal] PTCGraph window location
 
 
On 3/12/22 15:54, James Richters via fpc-pascal wrote:
Is there some way I can set the location of the pctgraph window before it is 
created so it just pops up where I want it to be?  I’m using Windows 10.
 
I’ve been re-locating it with SetWindowPos() which is ok if the window is going 
to be open for a while, but now I am trying to make a little program to display 
things and relocating the window is quite distracting.
 
It would also be nice to create the window without the title bar.
Currently, there's no way to do that. I'm planning to make it possible to 
change the title, without reopening the window, but I haven't thought about 
creating a window without a title, or moving it to a specific location. Btw, if 
the windows doesn't have a title, how can the user move it? Or do you want to 
move it manually, or just make it stay at a fixed location. These things are 
possible, but may be hard to do in a multi-platform way, e.g. in Linux, 
different window managers and desktop environments might ignore the location 
and place the window somewhere else. There are some crazy non-windows-like WMs 
there, like i3wm :)
Nikolay
 
James



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org 
<mailto:fpc-pascal@lists.freepascal.org> 
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] PTCGraph window location

2022-03-12 Thread James Richters via fpc-pascal
Is there some way I can set the location of the pctgraph window before it is
created so it just pops up where I want it to be?  I'm using Windows 10.
 
I've been re-locating it with SetWindowPos() which is ok if the window is
going to be open for a while, but now I am trying to make a little program
to display things and relocating the window is quite distracting.
 
It would also be nice to create the window without the title bar.
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Sorting a Stringlist on ValueFromIndex

2022-02-15 Thread James Richters via fpc-pascal
Thanks for the elegant solution Michael, but I'm having some issues 
implementing it.

I'm getting:

pastep.pas(28651,10) Warning: Function result does not seem to be set

28650  // Custom compare function
28651  function CompareValues(List: TStringList; Index1, Index2: Integer): 
Integer;
28652  
28653  begin
28654 
Result:=CompareText(List.ValueFromIndex[Index1],List.ValueFromIndex[Index2])
28655  end;

pastep.pas(28797,65) Error: Incompatible type for arg no. 1: Got "Pointer", 
expected ""

28797   AllLogLastRunStringList.CustomSort(@CompareValues);

The unit I'm putting this in has:
Unit PAStep;
{$Mode TP}{$I-}
{$modeswitch exceptions}
{$R+}

I can fix the first error with:
28654   
CompareValues:=CompareText(List.ValueFromIndex[Index1],List.ValueFromIndex[Index2])
{$Mode TP} doesn't like using 'result'

But I have no idea how I could fix the second error.  Any ideas?


James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Sorting a Stringlist on ValueFromIndex

2022-02-14 Thread James Richters via fpc-pascal
Is there a quick way to sort a stringlist on it's   .ValueFromIndex field
instead of it's   .Names field?
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Text Only printing on Windows.

2022-02-09 Thread James Richters via fpc-pascal
Thanks for the information.  It's not a Dymo printer, it's a Zebra printer.
But maybe it will work in a similar way..
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Text Only printing on Windows.

2022-02-09 Thread James Richters via fpc-pascal
Way back in the old Turbo Pascal days, it was super simple to send text to a
printer.   I had written a program that printed text on labels in the
order the labels were needed.. the whole thing took me less than an hour to
write and labels were spewing out of the printer.
I haven't had a need to print anything since then, but now, I want to do the
exact same thing.. print sequential text only labels from my FPC console
program. 
I can display the labels to the console window, or write them to a file. but
I'm just staring at my code at a total loss on how to send these simple
labels to my
USB label printer connected to a windows 10 64bit PC.  Is there no way to
just send text to printers anymore? 
I don't want to go through the windows print dialog for every label, and I
don't want to create one huge document of all the labels and print them all
at once..
I want my FPC console application to spit out the next in sequence single
label each time I push the space bar, without dealing with any the print
dialog or doing anything else.
This used to be so easy to do, but now it seems either very complicated or
impossible.  Does anyone know of a way to just send pain text
to a USB printer with FPC ,preferably without Lazarus?
 
James
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


  1   2   3   4   5   6   7   8   >