How to define variable in function Pascal - function

function F(x:real) : real;
begin
F := a*power(x,2);
end;
Guys, I need help.I am using Lazarus with form and I want to make a function with variable 'a' there. Variable a is an input just like a:= StrToInt(Edit1.Text);
Then how to define a there?

You should make a be an argument to the function.
function F(a: Integer; x: real): real;
begin
F := a*power(x,2);
end;
Further, using power for integer exponents is expensive and not terribly accurate. Use direct multiplication, in this case you can make use of sqr.
function F(a: Integer; x: real): real;
begin
F := a*sqr(x);
end;
Now, when you call the function you can use StrToInt(Edit1.Text) to obtain the value of a, which you pass on to the function. Or indeed you can use some other means to obtain a.
All of this is to avoid your arithmetic functions requiring knowledge of your UI.

Related

How to automatic return value of "PI" from function without assign in operation part of function body

My code is under , i will be gratefull for any suggestion
(* //const
//pi=3.1415926;
//uses
//mathh.inc; *)
var
r,pole_kola,obwod_kola: real;
function Pi: valreal;
begin
Pi:=3.1415926;
end;
procedure dane();
begin
read(r);
end;
procedure obliczenia();
begin
pole_kola:= {pi}Pi*r*r;
obwod_kola:= 2*{pi}Pi*r;
end;
procedure wyniki();
begin
writeln('pole koła: ',pole_kola:4:8);
writeln('obwód koła: ',obwod_kola:4:8);
end;
begin
writeln('podaj promien r: ');
dane();
obliczenia();
wyniki();
end.
How i can use function Pi :
https://www.freepascal.org/docs-html/rtl/system/pi.html
to return automatic value of "PI" from function without assign in operation part of function body if i try modify function get back
Function result does not seem to be set
function Pi() :valreal;
begin
end;
begin
WriteLn('pi = ', Pi():1:20);
end.
Compiling main.pas
main.pas(1,10) Warning: Function result does not seem to be set
Linking a.out
8 lines compiled, 0.1 sec
1 warning(s) issued
pi = 0.00000000000000000000
in program
 ./main
podaj promien r:
6
pole koła: 0.00000000
obwód koła: 0.00000000

In the task, I wanted to automatically use a ready value for PI (3.14…) without using my function. My function didn’t returned a value because I didn’t assigned one. Like we see here:
function Pi() :valreal;
begin
//here is nothing but must be returned a value
end;
begin
WriteLn('pi = ', Pi():1:20);
end.
Going by #derpirscher’s comment, the function written by hand always needs to return something. So I commented part of my syntax, and used the built-in function named PI. (Pascal includes that function.)
(* function pi: valreal; // If I define my own function, it must return a value
begin
pi:=3.1415926; // So in the body of the function, we must assign value
end; *)
We see that here
procedure obliczenia();
begin
pole_kola:= {pi}Pi*r*r; // using build in function
obwod_kola:= 2*{pi}Pi*r; // as above
end;
If we need to use the value of PI in our task/homework, we can use predefinied built-in functions because it is easier; it is good practice to use less syntax in our code.
Must remember: If we define a function i.e., named Pi ourselves, it has to return a value.
Under the comment, the entire syntax of my code with corrections:
var
r,pole_kola,obwod_kola: real;
(* function pi: valreal; // If I define my own function, it must return a value
begin
pi:=3.1415926; // So in the body of the function, we must assign value
end; *)
procedure dane();
begin
read(r);
end;
procedure obliczenia();
begin
pole_kola:= {pi}Pi*r*r; // using build in function
obwod_kola:= 2*{pi}Pi*r; // as above
end;
procedure wyniki();
begin
writeln('pole koła: ',pole_kola:4:8);
writeln('obwód koła: ',obwod_kola:4:8);
end;
begin
writeln('podaj promien r: ');
dane();
obliczenia();
wyniki();
end.

TwinCAT 3 using Union in function argument

I made union, which allow me to use same data as REAL or 4 bytes (Module in profibus device has 4 BYTE registers to write REAL floating point type value).
The union:
TYPE U_4Bytes2Real :
UNION
abDataBytes : ARRAY[0..3] OF BYTE;
rDataFloat : REAL;
END_UNION
END_TYPE
When I want to get access to this variable like REAL, I write:
U_4Bytes2Real.rDataFloat
When I want to get access to this variable like 4 BYTE ARRAY, I write:
U_4Bytes2Real.abDataBytes
I want to have a function, which gets REAL value, and inside it, I want to write it to the registers as an ARRAY of BYTES.
How to tell my function, that argument is REAL?
I' using function like that:
bFunResult := F_SetMod22(bDataGroup := 3, bChannel := 3, bDataFloat := 20.0, nTimeout := 100);
and i get error
Cannot convert type 'LREAL' to type 'U_4Bytes2Real'
Do I have to convert it INTO function, or there is some method to use union in function argument?
Answer
UNION is a STRUCT with a shared dataspace
This means anything that you can do with a STRUCT, you can do with a UNION. Whether that is use for inputs/outputs to a method, function, function block.
VAR
Data : U_4Bytes2Real;
END_VAR
F_Function( RealValue := Data.rDataFloat );
Example
Very simplest program to demonstrate this principle. It doesn't matter whether you are using a UNION or a STRUCT, they are accessed exactly the same.
TYPE st_Struct :
STRUCT
Value : REAL;
Packed : ARRAY [ 0..3 ] OF BYTE;
END_STRUCT
END_TYPE
TYPE u_Union :
UNION
Value : REAL;
Packed : ARRAY[0..3] OF BYTE;
END_UNION
END_TYPE
FUNCTION f_Sum : REAL
VAR_INPUT
A, B : REAL;
END_VAR
f_Sum := A + B;
PROGRAM MAIN
VAR
Str : st_Struct;
Uni : u_Union;
Result : REAL;
END_VAR
Result := f_Sum( Str.Value, Uni.Value );
For this answer I assume from your incomplete information:
Declaration assumption:
VAR
bFunResult : U_4Bytes2Real;
METHOD F_SetMod22 : LREAL
Then you can write:
bFunResult.rDataFloat = TO_REAL(F_SetMod22(...));
And later use:
bFunResult.abDataBytes
BUT !!!:
Be aware, that TO_REAL will cut off information if the returned LREAL does not fit into a REAL.
Your question and description of the problem is really poor. But from what I understand, here is what I can provide regarding setting the array values from the real value.
Creating union data type:
TYPE UnionType :
UNION
fReal : REAL;
arrBytes : ARRAY[0..3] OF BYTE;
END_UNION
END_TYPE
Creating function which takes input REAL and returns ARRAY[0..3] of BYTE:
// What is the purpose of this function, what does it return?
FUNCTION F_SetMod22 : ARRAY[0..3] OF BYTE;
VAR_INPUT
fValueIn : REAL;
END_VAR
VAR
arrResult : ARRAY[0..3] OF BYTE;
END_VAR
// Simply copy and paste the memory from the source address to the target address
MEMCPY(srcAddr := ADR(fValueIn), destAddr := ADR(arrResult[0]), n := SIZEOF(arrResult));
F_SetMod22 := arrResult;
Now calling the function in main. To the input we set the unions REAL value and we return the result to the array of the unions ARRAY value. To test the result, I will set a pointer to the union's ARRAY variable and set the value to a REAL test variable:
PROGRAM MAIN
VAR
uniValues : UnionType := (fReal := 30.0);
fResultTest : REAL;
pointerToReal : POINTER TO REAL;
END_VAR
uniValues.arrBytes := F_SetMod22(fValueIn := uniValues.fReal);
pointerToReal := ADR(uniValues.arrBytes[0]);
fResultTest := pointerToReal^;
two examples:
Value 199.99 was passed to the function. The returned array is set, test result is 199.99 as well:
Negative values test now:
I hope this helps. If this is not what you need, please give more information on the problem.

I am a beginner and using pascal. I don't know how to code the output. I am expecting the output to be the result of the function

I am a beginner and using pascal and i am trying this problem that i attach. What should i do next? I am trying to make this program work by showing the "ayam" Function. But i don't know how to code the rest.
function ayam(a, b:integer) :
integer;
var
m: integer;
begin
readln(a) ;
readln(b) ;
readln(m) ;
begin
if (b=0) then
ayam:= 1 else
ayam:= a * ayam(a, b-1) mod m;
end;
writeln(ayam);
end;
The first thing I should say is that when a question is to do with coursework, as is obviously the case here, there is an unwritten convention that we do not write an answer which simply does your programming task for you. So in the following, I have not commented on whether the code inside your ayam function actually correctly implements what is required - that is for you to do.
Secondly, you did not say which Pascal implementation you are using. I have written the code of this answer in Lazarus, the IDE for FreePascal (aka FPC), which is the best of the freeware Pascal implementations currently available.
The first thing to do with your code is to re-format it the way it should be formatted,
using indentation of statements to reflect the structure of the steps you are
trying to code. Basically, your eye should be able to follow the code structure
as easily as possible. This gives something like this:
function ayam(a, b:integer) : integer;
var
m: integer;
begin
readln(a) ;
readln(b) ;
readln(m) ;
begin
if (b=0) then
ayam:= 1
else
ayam:= a * ayam(a, b-1) mod m;
end;
writeln(ayam);
end;
With that change made, it is pretty obvious that there is something wrong with
the logic of your code, because a and b are declared as input variables to
the ayam function but your code actually reads in their values via the
readln statements inside the function. This is what made me think that you think
you have done all that's necessary to write your program. In fact, you have not. What you are missing
is some code which sets up the input parameters a and b (and m, see below) in some way and then
invokes your ayam function to calculate its value and then does something with
the result. At the moment, your code simply defines ayam but takes no steps
to use it. So, to get your ayam function to do anything, you need to write a complete
Pascal program that uses it. Something like this:
program ayamprogram;
{ the following declares some variables for the program to use }
var
varA,
varB,
varM,
varResult : Integer;
{ next, we define the ayam function }
function ayam(a, b, m:integer) : integer;
begin
begin
if (b=0) then
ayam:= 1
else
ayam:= a * ayam(a, b-1, m) mod m;
end;
end;
{ now we write the code of the program, which reads in the values to be
used by ayam, then invokes ("calls") ayam to calculate its value and
assign its value to the varResult variable and then outputs the calculated
result using the writeln statement
}
begin
{ this is the code of the program }
readln(varA);
readln(varB);
readln(varM);
varResult := ayam(varA, varB, varM);
writeln('function ayam evaluates to ', varResult);
readln; { this causes the program to pause so you can see the result of the writeln statement }
end. { end of program }
Note that I have used different variable names for the variables which are supplied to ayam, varA, varB, varM, from the variable names used inside ayam to avoid confusion between them.
Note also that as it is bad practice to read user input inside an executing function, the value to be used for M is read in before ayam is called and is supplied to ayam as a third parameter.
A point you need to consider regarding the expression
ayam:= a * ayam(a, b-1, m) mod m
is whether the mod m should operate on the value of ayam(a, b-1, m) or on the entire expression including the a * as well; if so, parentheses can enforce the evaluation order you need, by writing
ayam:= (a * ayam(a, b-1, m)) mod m

Returning a function in Ada

Is it possible, that a function can return a function in Ada? I am trying to get currying to work.
type Integer_Func_Type is access function (Y : Integer) return Integer;
function Add (X : Integer) return Integer_Func_Type is
function Inner (Y : Integer) return Integer is
begin
return X + Y;
end Inner;
begin
return Inner'Access;
end;
At the end, I do not want to provide all arguments of a function one at a time. For example: if x is a ternary function and y is curry(x), then I can use following function calls: y(a,b,c), y(a,b)(c), y(a)(b,c), y(a)(b)(c).
EDIT
I implemented 'Jacob Sparre Andersen' suggestions. But it does not look like currying will be easy to implement. I must implement every possible variant of any type I want to use in advance. Is this correct?
with Ada.Text_IO;
with R;
procedure Hello is
Add_Two : R.Test2 := (X => 2);
begin
Ada.Text_IO.Put_Line(Add_Two.Add(3)'Img);
end Hello;
r.adb
package body R is
function Add(A : Test2; Y : Integer) return Integer is
begin
return A.X + Y;
end Add;
end R;
r.ads
package R is
type Test is abstract tagged null record;
function Add(A : Test; Y : Integer) return Integer is abstract;
type Test2 is new Test with
record
X : Integer;
end record;
overriding
function Add(A : Test2; Y : Integer) return Integer;
end R;
This is how to do it with generics:
with Ada.Text_IO;
procedure Test is
-- shorthand Ada 2012 syntax; can also use full body
function Add (X, Y : Integer) return Integer is (X + Y);
generic
type A_Type (<>) is limited private;
type B_Type (<>) is limited private;
type Return_Type (<>) is limited private;
with function Orig (A : A_Type; B : B_Type) return Return_Type;
A : A_Type;
function Curry_2_to_1 (B : B_Type) return Return_Type;
function Curry_2_to_1 (B : B_Type) return Return_Type is
(Orig (A, B));
function Curried_Add is new Curry_2_to_1
(Integer, Integer, Integer, Add, 3);
begin
Ada.Text_IO.Put_Line (Integer'Image (Curried_Add (39)));
end Test;
As you see, it is quite verbose. Also, you need to provide a currying implementation for every count X of parameters of the original function and every number Y of parameters of the generated function, so you'd have a lot of Curry_X_to_Y functions. This is necessary because Ada does not have variadic generics.
A lot of the verbosity also comes from Ada not doing type inference: You need to explicitly specifiy A_Type, B_Type and Return_Type even though theoretically, they could be inferred from the given original function (this is what some functional programming languages do).
Finally, you need a named instance from the currying function because Ada does not support anonymous instances of generic functions.
So, in principle, currying does work, but it is not anything as elegant as in a language like Haskell. If you only want currying for a specific type, the code gets significantly shorter, but you also lose flexibility.
You can't do quite what you're trying to do, since Inner stops to exist as soon as Add returns.
You could do something with the effect you describe using tagged types.
One abstract tagged type with a primitive operation matching your function type.
And then a derived tagged type with X as an attribute and an implementation of the function matching Inner.
Many of the answers seem to deal with ways to have subprograms that deal with variable numbers of parameters. One way to deal with this is with a sequence of values. For example,
type Integer_List is array (Positive range <>) of Integer;
function Add (List : Integer_List) return Integer;
can be considered a function that takes an arbitrary number of parameters of type Integer. This is simple if all your parameters have the same type. It's more complicated, but still possible, if you deal with a finite set of possible parameter types:
type Number_ID is (Int, Flt, Dur);
type Number (ID : Number_ID) is record
case ID is
when Int =>
Int_Value : Integer;
when Flt =>
Flt_Value : Float;
when Dur =>
Dur_Value : Duration;
end case;
end record;
type Number_List is array (Positive range <>) of Number;
function Add (List : Number_List) return Number;
If you have to be able to handle types not known in advance, this technique is not suitable.

Pascal. Specify to use a variable instead of function with the same name>

I'm writing long digit arythmetics. This is a function for adding to longint long binary digits. I need to output the sum inside the function, to debug it. How could I do it, without creating new variables?
function add(var s1,s2:bindata;shift:longint):bindata;
var l,i:longint;
o:boolean;
begin
writeln(s1.len,' - ',s2.len);
o:=false;
l:=max(s1.len,s2.len);
add.len:=0;
for i:=1 to l do begin
if o then Begin
if s1.data[i+shift] then Begin
if (s2.data[i]) then add.data[i+shift]:=true
Else add.data[i+shift]:=false;
End
else if s2.data[i] then add.data[i+shift]:=false
else Begin
add.data[i+shift]:=true;
o:=false;
End;
End
Else Begin
if s1.data[i+shift] then Begin
if s2.data[i] then
Begin
add.data[i+shift]:=false;
o:=true;
End
Else add.data[i+shift]:=true;
End
else if s2.data[i] then add.data[i+shift]:=true
else add.data[i+shift]:=false;
End;
output(add); //Can I output a variable?
end;
add.len:=l;
if o then Begin
inc(add.len);
add.data[add.len]:=true;
End;
end;
You are accumulating the result of the function within the function result variable, which is generally fine, but uses an outdated style, and leads to exactly the problem you're facing here. You're trying to report an intermediate value of the function result, and to do that, you're trying to reference the name of the function, add. When you do that, though, the compiler interprets it as an attempt to report the function itself, rather than the expected return value of this particular invocation of the function. You'll get the address of the function, if output is defined to accept function addresses; otherwise, you'll get a compiler error.
If your compiler offers a certain common language extension, then you should use the implicit Result variable to refer to the intermediate return value instead of continuing to refer to it by the function name. Since Result is declared implicitly, you wouldn't have to create any other variables. The compiler automatically recognizes Result and uses it as an alias for the function's return value. Simply find every place you write add within the function and replace it with Result. For example:
if o then begin
Inc(Result.len);
Result.data[Result.len] := True;
end;
Turbo Pascal, Free Pascal, GNU Pascal, and Delphi all support the implicit Result variable, but if you've managed to get stuck with a compiler that doesn't offer that extension, then you have no choice but to declare another variable. You could name it Result, and then implement your function with one additional line at the end, like so:
function add(var s1, s2: bindata; shift: longint): bindata;
var
l, i: longint;
o: boolean;
Result: bindata;
begin
{
Previous function body goes here, but with
`add` replaced by `Result`
}
{ Finally, append this line to copy Result into the
function's return value immediately before returning. }
add := Result;
end;