What causes problems with this piece of code? - user-input

I was just wondering why this certain problem happens to me. If you can help me, I will appreciate it.
Program factorial;
uses crt;
var
f, i: Integer;
begin
f:=1;
for i:=1 to 5 do
f:= f * i;
write(f);
readkey;
end.
Okay, That works fine and the result is 120. And it's true.
Now, here's the problem. If I asked the user to enter the value of the number, it won't work.
Program factorial;
uses crt;
var
i,r: Integer;
begin
write('Enter the number');
read(r);
for i:=1 to r do
r:= r * i;
write(r);
readkey;
end.
If I wrote 5, the output will be 600.

You are using the value r as the stopping condition of the loop and modifying the value in the loop.
Program factorial;
uses crt;
var
i,r, f: Integer;
begin
write('Enter the number');
read(r);
f := 1;
for i:=1 to r do
f:= f * i;
write(f);
readkey;
end.

You reuse the r variable. If you input 5 for r your program will in effect one to many times. You should start with 1 as the first f.
Program factorial;
uses crt;
var
i,r, f: Integer;
begin
write('Enter the number');
read(r);
f:=1
for i:=1 to r do
f:= f * i;
write(r);
readkey;
end.

try:
Program factorial;
uses crt;
var
i,r,x: Integer;
begin
write('Enter the number');
read(x);
r:=1
for i:=1 to x do
r:= r * i;
write(r);
readkey;
end.

Related

Having problems with functions in Pascal

Here is the code:
Uses crt;
Type
mang = array[1..255] of Integer;
Var
N, X, Y : Integer;
A : mang;
Procedure Nhap(Var A : mang; Var N : Integer);
Var
i : Integer;
Begin
Clrscr;
Write('So luong phan tu: ');
Readln(N);
For i := 1 to N do begin
Write('Nhap phan tu thu ', i, ': ');
Readln(A[I]);
end;
End;
Procedure Xuat(Var A: mang; Var N: Integer);
Var
i : Integer;
Begin
For i := 1 to N do write(A[i], ' ');
Writeln;
End;
Function KTMangTang(Var A : mang; Var N : Integer) : Boolean;
Var
i, j : Integer;
Var
kt : Boolean;
Begin
kt := True;
i := 0;
For i := 1 to N-1 do
for j := i+1 to N do
if A[i] > A[j] then
kt := False;
KTMangTang := kt;
End;
Function KTMangDX(Var A : mang; Var N : Integer) : Boolean;
Var
i, j : Integer;
Var
kt : Boolean;
Begin
kt := True;
i := 0;
For i := 1 to N do
for j := N-i downto 1 do
if A[i] <> A[j] then
kt := False;
KTMangDX := kt;
End;
begin
Nhap(A, N);
Xuat(A, N);
if KTMangTang then
Writeln('Mang tang')
else
Writeln('Mang khong tang');
if KTMangDX then
Writeln('Mang doi xung')
else
Writeln('Mang khong doi xung');
readln;
End.
The boolean value KTMangTang and KTMangDX were supposed to work but they returned these errors:
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling 34.pas
34.pas(53,4) Error: Wrong number of parameters specified for call to "KTMangTang"
34.pas(28,10) Error: Found declaration: KTMangTang(var mang;var SmallInt):Boolean;
34.pas(55,4) Error: Wrong number of parameters specified for call to "KTMangDX"
34.pas(39,10) Error: Found declaration: KTMangDX(var mang;var SmallInt):Boolean;
34.pas(58,4) Fatal: There were 4 errors compiling module, stopping
Fatal: Compilation aborted
Error: C:\FPC\3.2.2\bin\i386-Win32\ppc386.exe returned an error exitcode
I tried not to use the "kt" boolean variable but it returned other errors.
P/S: I use Visual Studio Code with Free Pascal Compiler (32 bit). If anyone knows how to install the 64 bit Free Pascal IDE, please help me.
You have declared KTMangTang and KTMangDX as functions taking two parameters and returning a BOOLEAN. You have called them with no parameters. This doesn’t work. The errors in the compilation specifically tell you this.

Call by Reference and Call by Value Result

Well, there was a debate on the below code between me and my friend. We're a bit confused about the output it produce. Can someone clarify the call-by-reference and call-by value result for the below piece of code?
program params;
var i: integer;
a: array[1..2] of integer;
procedure p(x,y: integer);
begin
x := x + 1;
i := i + 1;
y := y + 1;
end;
begin
a[1] := 1;
a[2] := 2;
i := 1;
p( a[i],a[i] );
output( a[1],a[2] );
end.
The resulting output of this program in the case that the
parameters are transmitted to procedure p by value-result and by reference.
Call by Value
x and y in p are local variables initialized with the actual parameters, while i is a global variable, so the call p( a[i],a[i] ) is equivalent to:
x := 1 /* The value of a[i] */
y := 1 /* The value of a[i] */
x := 2 /* x + 1 */
i := 2 /* i + 1 */
y := 2 /* y + 1 */
and at the end the values 1, 2 are printed since they are the values of a[1], a[2] which weren't changed.
Call by Reference
Both x and y in p are alias for a[1] and (again) a[1] (since i = 1 when the procedure is called), so the call is equivalent to:
a[1] := 2 /* a[1] + 1 */
i := 2 /* i + 1 */
a[1] := 3 /* a[1] + 1 */
and at the end the values 3, 2 are printed.
Call by Name
Call by Name is equivalent to Call by Reference when simple variables are passed as parameters, but is different when you pass an expression that denotes a memory location, like a subscript. In this case the actual parameter is re-evaluated each time it is encountered. So in this case, this is the effect of the call of p( a[i],a[i] ):
a[1] := 2 /* since i = 1, the result is equal to a[1] + 1 */
i := 2 /* i + 1 */
a[2] := 3 /* since i is now 2, the result is equal to a[2] + 1 */
and at the end the values 2, 3 are printed. In practice the implementation calls an anonymous function (a “thunk”), each time it must evaluate a parameter.
Call by Value Result
Just to complete the discussion, here is the case for the value-result parameter passing, in which x and y are initialized at the beginning of the procedure execution with the values of the actual parameters, and, at the end of the execution of the procedure, are copied back to the original variables addresses:
x := 1 /* The value of a[i] */
y := 1 /* The value of a[i] */
x := 2 /* x + 1 */
i := 2 /* i + 1 */
y := 2 /* y + 1 */
a[1] := 2 /* the value of x is copied back to a[1] */
a[1] := 2 /* the value of y is copied back to a[1] (not a[2]!) */
and at the end the values 2, 2 are printed.
For a discussion of the different ways of passing parameters, see for instance this.
procedure p(x, y: integer);
begin
end;
In this case the varaibles passed as parameters are never modified. They are copied either to two registers (likely x: EAX and y: ECX) or to the stack. (depending on the compiler ABI)
procedure p(var x, y: integer);
begin
end;
In this case the original parameters are modified. x and y are pointers to the original variables passed as parameters.

Got "Boolean" expected "LongInt" pascal

I get this error on my insertion sort algorithm:
insertionsort.lpr(19,17) Error: Incompatible types: got "Boolean" expected "LongInt"
Here's the line 19 of my code
while j > 0 and A[j]>key do
I have tried googling all over the internet but i couldn't find any syntax errors or anything.
Here's the full code if it helps :
program instert;
uses crt;
const
N = 5;
var
i:integer;
j:integer;
key:integer;
A : Array[1..N] of Integer;
procedure insertionsort;
begin
for i := 2 to N do
begin
key := A[1];
j:= i - 1;
while j > 0 and A[j]>key do
begin
A[j+1] := A[j] ;
j := j-1;
end;
A[j+1] := key ;
end;
end;
begin
A[1]:= 9;
A[2]:= 6;
A[3]:= 7;
A[4]:= 1;
A[5]:= 2;
insertionsort;
end.
I also get the same error on the bubble sort algorithm i did. Here's the error line
bubblesort.lpr(26,14) Error: Incompatible types: got "Boolean" expected "LongInt"
Here's line 26 of my algorithm:
until flag = false or N = 1 ;
Here's the full code:
program bubblesort;
uses crt;
var
flag:boolean;
count:integer;
temp:integer;
N:integer;
A : Array[1..N] of Integer;
procedure bubblesort ;
begin
Repeat
flag:=false;
for count:=1 to (N-1) do
begin
if A[count] > A[count + 1] then
begin
temp := A[count];
A[count] := A[count + 1];
A[count] := temp;
flag := true;
end;
end;
N := N - 1;
until flag = false or N = 1 ;
end;
begin
A[1]:= 9;
A[2]:= 6;
A[3]:= 7;
A[4]:= 1;
A[5]:= 2;
N := 5;
bubblesort;
end.
In Pascal, boolean operators and and or have higher precedence than the comparison operators >, =, etc. So in the expression:
while j > 0 and A[j] > key do
Given that and has higher precedence, Pascal sees this as:
while (j > (0 and A[j])) > key do
0 and A[j] are evaluated as a bitwise and (since the arguments are integers) resulting in an integer. Then the comparison, j > (0 and A[j]) is evaluated as a boolean result, leaving a check of that with > key, which is boolean > longint. You then get the error that a longint is expected instead of the boolean for the arithmetic comparison.
The way to fix it is to parenthesize:
while (j > 0) and (A[j] > key) do ...
The same issue applies with this statement:
until flag = false or N = 1 ;
which yields an error because or is higher precedence than =. So you can parenthesize:
until (flag = false) or (N = 1);
Or, more canonical for booleans:
until not flag or (N = 1); // NOTE: 'not' is higher precedence than 'or'
When in doubt about the precedence of operators, parenthesizing is a good idea, as it removes the doubt about what order operations are going to occur.

How to convert integer to hex notation?

Using: Firebird 2.5.3
In a stored procedure (PSQL), converting a number from hex notation to decimal notation is done easily:
DECLARE VARIABLE I INTEGER;
BEGIN
I = CAST('0x0FFFE' AS INTEGER); -- I will have the value 65534
How can the reverse be achieved? ie. Convert from decimal notation to hex notation?
Short of using a UDF (which would mean using an external library file), the solution is to write a stored procedure to accomplish this:
SET TERM ^^ ;
CREATE PROCEDURE INTTOHEX (
INPUTNUMBER BigInt)
returns (
OUTPUTNUMBER VarChar(8))
AS
DECLARE VARIABLE Q BigInt;
DECLARE VARIABLE R BigInt;
DECLARE VARIABLE T BigInt;
DECLARE VARIABLE H VARCHAR(1);
DECLARE VARIABLE S VARCHAR(6);
begin
/* Max input value allowed is: 4294967295 */
S = 'ABCDEF';
Q = 1;
OUTPUTNUMBER = '';
T = INPUTNUMBER;
WHILE (Q <> 0) DO
BEGIN
Q = T / 16;
R = MOD(T, 16);
T = Q;
IF (R > 9) THEN
H = SUBSTRING(S FROM (R-9) FOR 1);
ELSE
H = R;
OUTPUTNUMBER = H || OUTPUTNUMBER ;
END
SUSPEND;
end ^^
SET TERM ; ^^
You can call this stored procedure from standard SQL or another stored procedure like this:
For example:
SELECT OUTPUTNUMBER FROM INTTOHEX(65534);
just did a short firebird function,
could handle bigger number,
maybe could help someone
CREATE OR ALTER FUNCTION INT64TOHEX (
C BIGINT)
RETURNS VARCHAR(32)
AS
DECLARE VARIABLE IREM INTEGER;
DECLARE VARIABLE HEX VARCHAR(32);
BEGIN
IREM = MOD(C, 0XFF);
HEX = '';
WHILE (IREM > 0) DO
BEGIN
HEX = SUBSTRING('0123456789abcdef' FROM BIN_SHR(BIN_AND(C, 0XFF), 4) + 1 FOR 1) || SUBSTRING('0123456789abcdef' FROM BIN_AND(BIN_AND(C, 0XFF), 15) + 1 FOR 1) || HEX;
C = BIN_SHR(C, 8);
IREM = MOD(C, 0XFF);
END
RETURN TRIM(HEX);
END

How to get/find the variable that caused Division By Zero error in delphi?

I know how to do basic exception handling. So i can raise a message on divide by zero using the 'try except' method.
What i would like to do is, find the variable that causes this error and then change its value on run time.
For Ex:
procedure Calculate();
var
a, b, c : Double;
begin
try
a := 4; //suppose i take this value from user and he enters 4
b := 0; //suppose i take this value from user and he enters 0
c := a/b;
ShowMessage(FloatToStr(c));
except
on E : EZeroDivide do
begin
ShowMessage('Exception message = '+E.Message);
//i am not sure how to identify that its variable 'b' that is causing the error and has to be changed by a default value
get(E....errorVaraiable);
E....errorVaraiable := 0.00001;
c := a/E....errorVariable;
ShowMessage(FloatToStr(c));
end;
end;
Please, can anyone help me with this?
Here's a modified version of your example that does what you want.
procedure Calculate();
var
a, b, c : Double;
begin
a := 4; //suppose i take this value from user and he enters 4
b := 0; //suppose i take this value from user and he enters 0
if IsZero(b) then
begin
ShowMessage('b cannot be 0')
end
else
begin
c := a/b;
ShowMessage(FloatToStr(c));
end;
end;