### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Doesn't evaluate the function  (Read 405 times)

#### garandr

• New Member
• Posts: 10
##### Doesn't evaluate the function
« on: November 27, 2020, 06:33:20 pm »
Code: Pascal  [Select][+][-]
1. unit Unit2;
2.
3. {\$mode objfpc}{\$H+}
4.
5. interface
6.
7. uses
8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,Math;
9.
10. type
11.
12.   { TForm2 }
13.
14.   TForm2 = class(TForm)
15.     Button1: TButton;
16.     Edit1: TEdit;
17.     Edit2: TEdit;
18.     procedure Button1Click(Sender: TObject);
19.   private
20.
21.   public
22.
23.   end;
24.
25. var x,y,exp:real;
26.
27.   Form2: TForm2;
28.
29. implementation
30.
31. {\$R *.lfm}
32.
33. { TForm2 }
34.
35. procedure TForm2.Button1Click(Sender: TObject);
36. begin
37.   x:=StrToInt(Edit1.Text);
38.    begin
39.        if x <=-3 then
40.            y:=abs((2*tag*(x-7)))+power(10,1.5);
41.       if (x>-3) and (x<=0) then
42.            y:=5*power(x+1,2)+5*((power(x+3/x+2,0.25)+2))/(x-3);
43.
44.       if x>0 then
45.       y:=power(exp,-4*x)-7*x
46. else
47.   Edit2.Text:=('error');
48.
49.         Edit2.Text:=FloatToStr(y);
50.
51. end;
52. end;
53.
54. end.
55.

#### wildfire

• Jr. Member
• Posts: 77
##### Re: Doesn't evaluate the function
« Reply #1 on: November 27, 2020, 06:41:35 pm »
Try...

Quote
Code: [Select]
`    unit Unit2;         {\$mode objfpc}{\$H+}         interface         uses      Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,Math;         type           { TForm2 }           TForm2 = class(TForm)        Button1: TButton;        Edit1: TEdit;        Edit2: TEdit;        procedure Button1Click(Sender: TObject);      private           public           end;         var x,y,exp:real;           Form2: TForm2;         implementation         {\$R *.lfm}         { TForm2 }         procedure TForm2.Button1Click(Sender: TObject);    begin      x:=StrToInt(Edit1.Text);      if x <=-3 then        y:=abs((2*tag*(x-7)))+power(10,1.5);      else if (x>-3) and (x<=0) then        y:=5*power(x+1,2)+5*((power(x+3/x+2,0.25)+2))/(x-3);      else if x>0 then        y:=power(exp,-4*x)-7*x        else                                         // <------------ Should never be reached        Edit2.Text:=('error');           Edit2.Text:=FloatToStr(y);   end;     end. `

Edit: the code could be tidied up a little, but I'll leave that for you to figure out.
« Last Edit: November 27, 2020, 06:46:50 pm by wildfire »
Windows 10 64bit version 1809
Laz 2.0.0 FPC 3.0.4

#### wp

• Hero Member
• Posts: 7964
##### Re: Doesn't evaluate the function
« Reply #2 on: November 27, 2020, 06:50:27 pm »
What is "tag"?

For calculating the power of 2 it is more efficient to call the function sqr instead of calling power(..., 2)

The center formula, the part with the 4th root, is lacking brackets around the numerator and denominator expressions:
Code: Pascal  [Select][+][-]
1.  y:=5*sqr(x+1)+5*((power((x+3)/(x+2),0.25)+2))/(x-3);  // <--- brackets around x+3 and (x-2

Use "else" between the "if" conditions to simplify the code. Basically
Code: Pascal  [Select][+][-]
1.  if (x <= -3) then
2.    y := ....
3.   else if (x <= 0) then  // no need to check for x >-3 because the opposite case has been handled already
4.     y := ...
5.   else   // no need to check for y > 0 because the case has been handled by the previous two if's.
6.     y := ...

Do not name a variable "exp" because there is an equally named function - this leads to unnecessary confusion. But I guess you want to calculate the exponential of -4x:
Code: Pascal  [Select][+][-]
1.   y := exp(-4*x) - 7*x;

And I don't know if your code is called often. When this is true you should pre-calculate the constant power(10, 1.5) in the first expression: 10^1.5 = 10^(3/2) = sqrt(1000)
Code: Pascal  [Select][+][-]
1. const
2.   sqrt1000 = sqrt(1000.0);
3. ...
4.   y := abs(...) + sqrt1000);
« Last Edit: November 27, 2020, 07:50:54 pm by wp »
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### devEric69

• Sr. Member
• Posts: 420
##### Re: Doesn't evaluate the function
« Reply #3 on: November 27, 2020, 07:06:09 pm »
Another tip: multiplication by 2 is faster when writing shl 1 .

As i*2 could be written i shl 1, then (2*tag) can be written (2 shl 1) in your calculation. But it's less understandable when we reread it.

« Last Edit: November 27, 2020, 07:11:53 pm by devEric69 »
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

#### marcov

• Global Moderator
• Hero Member
• Posts: 9023
• FPC developer.
##### Re: Doesn't evaluate the function
« Reply #4 on: November 27, 2020, 07:43:25 pm »
Another tip: multiplication by 2 is faster when writing shl 1 .

Really?

If I try  it with

Code: Pascal  [Select][+][-]
1.   m:=i*2;
2.   n:=j shl 1 ;
3.

compiling with optimization, the generated assembler code is the same:

Code: Pascal  [Select][+][-]
1. # [9] m:=i*2;
2.         shll    \$1,%eax
3. # Var m located in register eax
4. # [10] n:=j shl 1 ;
5.         shll    \$1,%edx
6.

IOW this kind of "tricks" might have been the case with prehistoric non-optimizing 16-bit compilers, but are outdated in anything semi-modern. (as in of this century)

#### wp

• Hero Member
• Posts: 7964
##### Re: Doesn't evaluate the function
« Reply #5 on: November 27, 2020, 07:55:28 pm »
This is a similar question as that of https://forum.lazarus.freepascal.org/index.php/topic,52320.msg385306.html#msg385306 posted by another new user. Or are you the same user? ...
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### devEric69

• Sr. Member
• Posts: 420
##### Re: Doesn't evaluate the function
« Reply #6 on: November 27, 2020, 08:11:48 pm »
IOW this kind of "tricks" might have been the case with prehistoric non-optimizing 16-bit compilers, but are outdated in anything semi-modern. (as in of this century)

To be more comprehensive, I was looking for the usefulness of such a code (shl 1) this afternoon on the forum. I found it elsewhere, and posted it there for memento \ memory, as a bad applied example.

Here's the function using this trick, which I've commented on, to understand it:

Code: Pascal  [Select][+][-]
1. procedure ReplaceMany(var sTr: String; aR: array of String);
2. {
3.  Calling example:
4. ~~~~~~~~~~~~~~~~~~~
5. ReplaceMany(Template, ['?VERSION?' (* i.e. cell [0==>1] *),           GetOriginalProjectVersion
6.                       ,'?EXECUTABLE?' (* i.e. cell [2==>3] *),        GetExecutableFilenameRelative
7.                       ,'?PROJECT?' (* i.e. cell [4==>5] *),           GetProjectInformationFilenameRelative
8.                       ,'?TEMPFOLDER?' (* i.e. cell [6==>7] *),        GetTempPathAbsolute
9.                       ,'?CP?' (* i.e. cell [8==>9] *),                GetCopyCommand
10.                       ]);
11. }
12. var
13.   i, j: Integer;
14. begin
15.   { for half of a 2-dim. table, i.e. for each line i.e. each [index == >value] }
16.   for i := 0 to High(aR) div 2 do begin
17.     j := i shl 1;{== i * 2}
18.     if Trim(aR[j+1]) = '' then
19.       raise Exception.Create('procedure ReplaceMany ==> the placeholder ' + aR[j] + ' is empty!' + LF + 'Please, set a value.');
20.     sTr := StringReplace(sTr, aR[j]{placeholder}, aR[j+1]{value}, [rfReplaceAll]);
21.   end;
22. end;

That said, apart from manipulating individual bits, the use of this trick is inappropriate in a mathematical calculation.
« Last Edit: November 29, 2020, 05:44:37 pm by devEric69 »
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.