Recent

Author Topic: Doesn't evaluate the function  (Read 398 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: 7918
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: 417
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: 8998
  • 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: 7918
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: 417
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.

 

TinyPortal © 2005-2018