Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
Solved

# Multipling and Dividing

Posted on 2000-02-25
Medium Priority
363 Views
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.

0
Question by:rarigo
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 22
• 10
• 5
• +4

LVL 27

Expert Comment

ID: 2557448
? not capable to multiply and divide ?
0

LVL 27

Expert Comment

ID: 2557458
does

x div y
x * y

not work?
0

Author Comment

ID: 2557467
Nope.  Does not work if x or y are longint type.
0

Author Comment

ID: 2557476
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.
0

LVL 20

Expert Comment

ID: 2557614
Can you do this?

result := x shr 1;   // result := x div 2;
result := x shl 1;   // result := x * 2;

0

LVL 1

Expert Comment

ID: 2557619
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.
0

LVL 1

Expert Comment

ID: 2557622

Heh ;O)

Speedier typer than me :O)

Tim.
0

Author Comment

ID: 2557779

Shl and Shr didn't work :-(((

0

Expert Comment

ID: 2557790

Hi !

Strange machine you have .. what kind of CPU has it ?

Sascha
0

Author Comment

ID: 2557807
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
0

Expert Comment

ID: 2557816

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
0

Author Comment

ID: 2557871
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

0

LVL 27

Expert Comment

ID: 2557891
maybe you should use a real-typ instead a longint
0

Expert Comment

ID: 2557894
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
0

Author Comment

ID: 2557896
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
0

LVL 27

Expert Comment

ID: 2557907
numeric-processing to software
emulation to on
0

Author Comment

ID: 2557908
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

0

Author Comment

ID: 2557913
Hi kretzschmar,

I've played around with all these too :-((

Reginaldo
0

Expert Comment

ID: 2557931

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 ..

0

Author Comment

ID: 2557944
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.

0

Expert Comment

ID: 2557977

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
0

Author Comment

ID: 2558016
Hi Sascha,

Yeah, It does have problems with 32 bits values but there's not compiler options to solve this.

Reginaldo
0

Author Comment

ID: 2558030
Lunch time....
0

Author Comment

ID: 2558323
Hi,

Does any one have any improvements for the routine posted above?

Reginaldo
0

Expert Comment

ID: 2558435

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)
0

Author Comment

ID: 2558788
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

0

Expert Comment

ID: 2558798

I think it's the best when you buy a new computer.
0

Author Comment

ID: 2558811
Hi Sascha,

We're not talking about my computer but about those little machines. Remember??

0

Expert Comment

ID: 2558846

What kind of "calculator" you ever have .. I think it's a bit too "little" .. ?!

0

Author Comment

ID: 2558922
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
0

Author Comment

ID: 2558939
Sorry.

sailors man should read sails men

0

Expert Comment

ID: 2558942

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 ..
0

Author Comment

ID: 2559108
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;

I'm just asking a way to improve it a bit.

Reginaldo
0

Expert Comment

ID: 2559190

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

0

Author Comment

ID: 2559274
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

0

LVL 3

Expert Comment

ID: 2560627
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 !

0

LVL 3

Accepted Solution

Alisher_N earned 652 total points
ID: 2560660
ok, if above won't help also ;-) try this:

{\$G-}
Procedure Div2( var X : Longint ); assembler;
asm
std
lds   si, X
push  ds
pop   es
mov   di,si
mov   cx,4
mov   ah,0
@@L2:
xor   bl,bl
lodsb
shr   al,1
or    al,ah
stosb
mov   ah,bl
push  cx
mov   cx,7
shl   ah,cl
pop   cx
loop  @@L2
end;

0

Author Comment

ID: 2561206
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

0

LVL 3

Expert Comment

ID: 2561223
hope so...
at least it works for me ;-))
0

LVL 1

Expert Comment

ID: 2564182

function DivBy2(Num:Longint):Longint;
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):Longint;
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):Longint;
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.
0

Author Comment

ID: 2564710
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..
0

Author Comment

ID: 2564713
Hi FatMan,

Your procedure is the same of mine. Not that fast. In fact my first version was more like it.

Sinceramente,
Reginaldo

0

LVL 3

Expert Comment

ID: 2568177
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
or    al,ah
stosb
mov   ah,bl
loop  @@L2
pop   ds
end;

arrivederchi ;-)
0

LVL 3

Expert Comment

ID: 2568183
OUGH! Sorry !
name of procedure must be Mult2, of course ! #\$%# ! ;-)

0

Author Comment

ID: 2568953
arrivederchi ;-)
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have toâ€¦
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi databaseâ€¦
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vulnâ€¦
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a qâ€¦
###### Suggested Courses
Course of the Month10 days, 7 hours left to enroll