rarigo
asked on
Multipling and Dividing
Hi Experts Guys,
I know this question should be post to Pascal area but, seems to me this area is more visited so...
I'm working on a little machine that's no capable of making divisions or multiplications using longints variables.
So I really need a fast routine to multiply and divide using only additions and subtractions.
Sinceramente,
Reginaldo
P.S1.: It's enough to divide by two only.
I know this question should be post to Pascal area but, seems to me this area is more visited so...
I'm working on a little machine that's no capable of making divisions or multiplications using longints variables.
So I really need a fast routine to multiply and divide using only additions and subtractions.
Sinceramente,
Reginaldo
P.S1.: It's enough to divide by two only.
? not capable to multiply and divide ?
does
x div y
x * y
not work?
x div y
x * y
not work?
ASKER
Nope. Does not work if x or y are longint type.
ASKER
These machine is capable of holding a longint variable. So "you can work" with these kinda of variable as long as you don't try to multiply or divide them. 'Cause this will cause a divide by zero error.
Can you do this?
result := x shr 1; // result := x div 2;
result := x shl 1; // result := x * 2;
Regards, Madshi.
result := x shr 1; // result := x div 2;
result := x shl 1; // result := x * 2;
Regards, Madshi.
does :
x shr 1
work for divide by 2?
and
x shl 1
work for multiply by 2?
ie:
x := 4 ;
x := x shl 1 ;
x _should_ then equal 8 ;O)
Tim.
x shr 1
work for divide by 2?
and
x shl 1
work for multiply by 2?
ie:
x := 4 ;
x := x shl 1 ;
x _should_ then equal 8 ;O)
Tim.
Oh Madshi >8O(
Heh ;O)
Speedier typer than me :O)
Tim.
Heh ;O)
Speedier typer than me :O)
Tim.
ASKER
Hi Madshi and Tim,
Shl and Shr didn't work :-(((
Shl and Shr didn't work :-(((
Hi !
Strange machine you have .. what kind of CPU has it ?
Sascha
ASKER
Hi Sascha,
In fact. I don't know. I have lots of them around here but can't find a manual. it works with a rom dos version. It's a TRIGON - TriPC.
Reginaldo
In fact. I don't know. I have lots of them around here but can't find a manual. it works with a rom dos version. It's a TRIGON - TriPC.
Reginaldo
Hi Reg,
I think, if Delphi is running on it, the full command set should be available without problems.
What kind of error occurs (compiler error / runtime error / ..) ?
Greets
Sascha
ASKER
Hi Sascha,
Oops,
As I said these question doesn't exactly belong here it should be post to Pascal area...
It doesn't have Delphi running on it. I'm programming using Pascal 6.0
Reginaldo
Oops,
As I said these question doesn't exactly belong here it should be post to Pascal area...
It doesn't have Delphi running on it. I'm programming using Pascal 6.0
Reginaldo
maybe you should use a real-typ instead a longint
Hi Reg,
I have programmed in TP6/BP7 before I started with Delphi.
Cannot remember any problems with div/mult operations on any machine.
Perhaps you could post the code making trouble ..
Sascha
I have programmed in TP6/BP7 before I started with Delphi.
Cannot remember any problems with div/mult operations on any machine.
Perhaps you could post the code making trouble ..
Sascha
ASKER
Hi,
Right now i'm using this homemade function below to divide by 2. On my PC it works fine but on that machine it's kinda of slow. In fact i'm posting these question just to find a better solution.
function Divid( Num : LongInt ) : LongInt;
Var
i,j,n : LongInt;
done : Boolean;
begin
n := 450;
if n > Num then
n := Num;
i := 0; j := num;
Done := false;
repeat
while i < j do
begin
Inc( i, n );
Dec( j, n );
end;
if ( j + 1 = i ) or ( j = i ) then
Done := true
else
begin
Inc( j, n );
Dec( i, n );
Dec( n );
end;
until done;
Divid := j
end;
Any ideas?
Sinceramente,
Reginaldo
Right now i'm using this homemade function below to divide by 2. On my PC it works fine but on that machine it's kinda of slow. In fact i'm posting these question just to find a better solution.
function Divid( Num : LongInt ) : LongInt;
Var
i,j,n : LongInt;
done : Boolean;
begin
n := 450;
if n > Num then
n := Num;
i := 0; j := num;
Done := false;
repeat
while i < j do
begin
Inc( i, n );
Dec( j, n );
end;
if ( j + 1 = i ) or ( j = i ) then
Done := true
else
begin
Inc( j, n );
Dec( i, n );
Dec( n );
end;
until done;
Divid := j
end;
Any ideas?
Sinceramente,
Reginaldo
or adjust the compiler-options
numeric-processing to software
emulation to on
numeric-processing to software
emulation to on
ASKER
Hi Sascha,
Any code like:
Var
a,b,c : Longint;
begin
a := 1; b := 2;
c :=a * b;
c := b div a;
c := b shl 1;
c := b shr 1;
end.
will cause divide by zero error.
Reginaldo
Any code like:
Var
a,b,c : Longint;
begin
a := 1; b := 2;
c :=a * b;
c := b div a;
c := b shl 1;
c := b shr 1;
end.
will cause divide by zero error.
Reginaldo
ASKER
Hi kretzschmar,
I've played around with all these too :-((
Reginaldo
I've played around with all these too :-((
Reginaldo
Hi Reg,
hmm .. cannot think what kinda problem this could be.
Perhaps you should write a very basic program to test if the problem comes from yer hardware or from the software ..
eg..
Program test;
uses crt;
var c : integer;
begin
clrscr;
c:=1*2;
end.
(hope I remember the TP syntax correctly... ;)
It's a very long time ago ..
ASKER
Hi Sascha,
I've already done these tests. this test of yours won't cause any problem because c is an integer but would cause if c were a longint.
I've already done these tests. this test of yours won't cause any problem because c is an integer but would cause if c were a longint.
Hi Reg,
Sounds like yer CPU has problems working with 32bit values ...
AFAIK the TP compiler can do software-calculating too .. perhaps you should activate the according function.
Greets
Sascha
ASKER
Hi Sascha,
Yeah, It does have problems with 32 bits values but there's not compiler options to solve this.
Reginaldo
Yeah, It does have problems with 32 bits values but there's not compiler options to solve this.
Reginaldo
ASKER
Lunch time....
ASKER
Hi,
Does any one have any improvements for the routine posted above?
Reginaldo
Does any one have any improvements for the routine posted above?
Reginaldo
Declare the variable as a Real, you
have decimals AND you can use the software calculating functions from the compiler.
(the real-types are much bigger than normal integer .. possibly your pc simply can't handle longint)
ASKER
Sorry. But i can't accept your comment as an answer to my question.
It doesn't solve my problem in any way. The seek function doesn't accept real variables and to convert those real type variables to longint takes long than my routine post above.
After all the question is how could i multiply and divide longint variables using addition and subtraction.
Sinceramente,
Reginaldo
It doesn't solve my problem in any way. The seek function doesn't accept real variables and to convert those real type variables to longint takes long than my routine post above.
After all the question is how could i multiply and divide longint variables using addition and subtraction.
Sinceramente,
Reginaldo
I think it's the best when you buy a new computer.
ASKER
Hi Sascha,
We're not talking about my computer but about those little machines. Remember??
We're not talking about my computer but about those little machines. Remember??
What kind of "calculator" you ever have .. I think it's a bit too "little" .. ?!
ASKER
Hi Sascha,
Let's go on with this discussion because today is Friday and my day is almost over by now. I work on Pentium II 450 Mz 128MB and that's my machine. But some sailors man of these company work out there on the streets with those little machines. And I'm reprogramming the program that runs on these machines.
Got it?
Reginaldo
Let's go on with this discussion because today is Friday and my day is almost over by now. I work on Pentium II 450 Mz 128MB and that's my machine. But some sailors man of these company work out there on the streets with those little machines. And I'm reprogramming the program that runs on these machines.
Got it?
Reginaldo
ASKER
Sorry.
sailors man should read sails men
sailors man should read sails men
Ahh .. I see ..
But I don't have any further ideas how it could work .. really.
I think you have to make the compromise
with the real-types ..
If yer machine cannot handle 32bit integers, you cannot write a routine which divides them ..
The conversion from Float to Integer
isn't that slow .. just truncate them ..
where's the problem .. yer streetworkers have to wait 0,5 sec longer ? c'mon ..
ASKER
Have you tried this routine I've posted above?
function Divid( Num : LongInt ) : LongInt;
Var
i,j,n : LongInt;
done : Boolean;
begin
n := 450;
if n > Num then
n := Num;
i := 0; j := num;
Done := false;
repeat
while i < j do
begin
Inc( i, n );
Dec( j, n );
end;
if ( j + 1 = i ) or ( j = i ) then
Done := true
else
begin
Inc( j, n );
Dec( i, n );
Dec( n );
end;
until done;
Divid := j
end;
It's not that bad.
I'm just asking a way to improve it a bit.
Reginaldo
function Divid( Num : LongInt ) : LongInt;
Var
i,j,n : LongInt;
done : Boolean;
begin
n := 450;
if n > Num then
n := Num;
i := 0; j := num;
Done := false;
repeat
while i < j do
begin
Inc( i, n );
Dec( j, n );
end;
if ( j + 1 = i ) or ( j = i ) then
Done := true
else
begin
Inc( j, n );
Dec( i, n );
Dec( n );
end;
until done;
Divid := j
end;
It's not that bad.
I'm just asking a way to improve it a bit.
Reginaldo
Ok .. before I can try,
a few questions:
1. What is the biggest/smallest number you'll have to divide ?
2. What if the result would have decimals .. should they be truncated or rounded or what ?
3. Your PC can't handle shr/shl in no way ? (try it with a byte/integer type)
I should know these things .. sorry
ASKER
ok.
1. As big as a longint can hold or as small as 2
2. The result must be integer and truncated
3. Don't confuse my PC and that " litte pc". My PC is a normal one but that where this program is supposed to run can NOT handle shr/shl in no way if the variable is a longint
1. As big as a longint can hold or as small as 2
2. The result must be integer and truncated
3. Don't confuse my PC and that " litte pc". My PC is a normal one but that where this program is supposed to run can NOT handle shr/shl in no way if the variable is a longint
hey rarigo!
I think you CPU is < 386 (XT or something) so you have to put {$G-} directive to turn OFF extended commands generation, after that longint should work fine... try this !
I think you CPU is < 386 (XT or something) so you have to put {$G-} directive to turn OFF extended commands generation, after that longint should work fine... try this !
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Alisher
Thanks for your time. I just cant try this till Monday at work. If it works or helps in any way I'll let you know. Ok?
'See' ya there...
Reginaldo
Thanks for your time. I just cant try this till Monday at work. If it works or helps in any way I'll let you know. Ok?
'See' ya there...
Reginaldo
hope so...
at least it works for me ;-))
at least it works for me ;-))
What about this:
function DivBy2(Num:Longint):Longin t;
var Result:Longint;
begin
Result:=0;
while (N>0)and(Num>2) do
begin
Dec(Num,2); {or Num:=Num-2}
Inc(Result) {or Result:=Result+1}
end;
DibBy2:=Result;
end;
or more general one:
function DivideByN(Num,N:Longint):L ongint;
var Result:Longint;
begin
Result:=0;
while (N>0)and(Num>N) do
begin
Dec(Num,N); {or Num:=Num-N}
Inc(Result) {or Result:=Result-1}
end;
DivByN:=Result;
end;
Similar way to multiply:
function MultByN(Num,N:Longint):Lon gint;
var Result:Longint;
begin
Result:=0;
if N>Num
then
while Num>0 do
begin
Dec(Num);
Inc(Result,N)
end
else
while N>0 do
begin
Dec(N);
Inc(Result,Num)
end;
MultByN:=Result;
end;
I have not considered the signs of Num and N, but there is a way to do it.
Jo.
function DivBy2(Num:Longint):Longin
var Result:Longint;
begin
Result:=0;
while (N>0)and(Num>2) do
begin
Dec(Num,2); {or Num:=Num-2}
Inc(Result) {or Result:=Result+1}
end;
DibBy2:=Result;
end;
or more general one:
function DivideByN(Num,N:Longint):L
var Result:Longint;
begin
Result:=0;
while (N>0)and(Num>N) do
begin
Dec(Num,N); {or Num:=Num-N}
Inc(Result) {or Result:=Result-1}
end;
DivByN:=Result;
end;
Similar way to multiply:
function MultByN(Num,N:Longint):Lon
var Result:Longint;
begin
Result:=0;
if N>Num
then
while Num>0 do
begin
Dec(Num);
Inc(Result,N)
end
else
while N>0 do
begin
Dec(N);
Inc(Result,Num)
end;
MultByN:=Result;
end;
I have not considered the signs of Num and N, but there is a way to do it.
Jo.
ASKER
Hi Alisher;
{$G-} didn't work but your div2 routine is very fast and that's all I asked for.
Thanks,
Sinceramente,
Reginaldo
PS : I had to change it a little to work. Procedure Div2( var X : Longint ); assembler;
asm
PUSH DS ///////
...
loop @@L2
POP DS /////////////
end;
PS : Dont you have a assembler procedure to multiply a longint somewhere in your HD? Hehehe
Tks again..
{$G-} didn't work but your div2 routine is very fast and that's all I asked for.
Thanks,
Sinceramente,
Reginaldo
PS : I had to change it a little to work. Procedure Div2( var X : Longint ); assembler;
asm
PUSH DS ///////
...
loop @@L2
POP DS /////////////
end;
PS : Dont you have a assembler procedure to multiply a longint somewhere in your HD? Hehehe
Tks again..
ASKER
Hi FatMan,
Your procedure is the same of mine. Not that fast. In fact my first version was more like it.
Thanks for your time anyway.
Sinceramente,
Reginaldo
Your procedure is the same of mine. Not that fast. In fact my first version was more like it.
Thanks for your time anyway.
Sinceramente,
Reginaldo
strange thing... yesterday I post one more comment, but it is on here... So I have retype it again ;-(
I don't have this code 'on my HDD' because I actually have written it in 15 minutes to answer your question ;-)
I have optimized Div2, so it will be even more faster ;-), you have to change (in bottom part of Div2)
push cx
mov cx,7
shl ah,cl
pop cx
to:
ror ah,1
;-)
and this is Mult2
{$G-}
Procedure Div2( var X : Longint ); assembler;
asm
push ds
cld
lds si, X
push ds
pop es
mov di,si
mov cx,4
mov ah,0
@@L2:
xor bl,bl
lodsb
shl al,1
adc bl,0
or al,ah
stosb
mov ah,bl
loop @@L2
pop ds
end;
arrivederchi ;-)
I don't have this code 'on my HDD' because I actually have written it in 15 minutes to answer your question ;-)
I have optimized Div2, so it will be even more faster ;-), you have to change (in bottom part of Div2)
push cx
mov cx,7
shl ah,cl
pop cx
to:
ror ah,1
;-)
and this is Mult2
{$G-}
Procedure Div2( var X : Longint ); assembler;
asm
push ds
cld
lds si, X
push ds
pop es
mov di,si
mov cx,4
mov ah,0
@@L2:
xor bl,bl
lodsb
shl al,1
adc bl,0
or al,ah
stosb
mov ah,bl
loop @@L2
pop ds
end;
arrivederchi ;-)
OUGH! Sorry !
name of procedure must be Mult2, of course ! #$%# ! ;-)
name of procedure must be Mult2, of course ! #$%# ! ;-)
ASKER
arrivederchi ;-)