From: knowledgehungry on

Dear Sir,
I know how to do maths using maths co-processor. I can also do
addition/substraction/multiplication WITHOUT maths co-processor.
But I am stuck up with Division. Can anybody tell me how to perform
division without getting divide overflow and WITHOUT using maths
co-processor using assembly language ?

I would also like to know hoe to calculate log and antilog WITHOUT
using maths co-processor.

I know how to convert ascii to float or double using maths co-processor
but do not know how to do conversion WITHOUT using maths coprocessor.
Please tell me how to do these things in assembly language. Are there
any good sites for mathematics using assembly language ?

-Mahesh Shrikrishna Chavan
chavanmaheshs(a)yahoo.co.in

From: Richard Cooper on
On Fri, 07 Oct 2005 15:01:47 -0400, knowledgehungry
<chavanmaheshs(a)yahoo.co.in> wrote:

> Can anybody tell me how to perform
> division without getting divide overflow and WITHOUT using maths
> co-processor using assembly language ?

Well, the easy way would be the divide instruction. But short of that,
you just have to do long division.

Say you want to divide 13482 by 234.

In binary, these are 11010010101010 and 11101010. So it's done like this:

________________
11101010 ) 11010010101010

Then we go here:

__________1_____
11101010 ) 11010010101010
-11101010
--------------
1011101101010

And then we go here:

__________11____
11101010 ) 11010010101010
-11101010
--------------
1011101101010
-11101010
-------------
100011001010

Then we go here:

__________111___
11101010 ) 11010010101010
-11101010
--------------
1011101101010
-11101010
-------------
100011001010
-11101010
------------
101111010

Then we go like this:

__________11100_
11101010 ) 11010010101010
-11101010
--------------
1011101101010
-11101010
-------------
100011001010
-11101010
------------
101111010

Then we do like this:

__________111001
11101010 ) 11010010101010
-11101010
--------------
1011101101010
-11101010
-------------
100011001010
-11101010
------------
101111010
-11101010
---------
10010000

And then we do this:

__________111001 R 10010000
11101010 ) 11010010101010
-11101010
--------------
1011101101010
-11101010
-------------
100011001010
-11101010
------------
101111010
-11101010
---------
10010000

And so 13482 divided by 234 is 57 remainder 144. (And how surprised am I
that I didn't screw that up somewhere...)

As you see, it amounts to a loop of a shift right, a compare, and a
possible subtraction.

> I would also like to know hoe to calculate log and antilog WITHOUT
> using maths co-processor.

That I learned myself from MathWorld, and so I guess a link there is in
order:
http://mathforum.org/library/drmath/view/55566.html

Pay attention to what it says about how the function takes longer
depending on what numbers you put into it. For example, calculating
log_10(12345678) will take an impossibly long time, but calculating
log_10(1.2345678) will be quite fast, and then you just multiply your
answer by 7 (which is from the 10^7 that you divided 12345678 by) and
you've got the answer to log_10(12345678).

However, you'll notice that the logarithm formulas are for log_e. To fix
that, you just divide by the log_e of the base that you really want. For
example, log_10(12345678) is the same as log_e(12345678) divided by
log_e(10). If you're doing a lot of log_10 it's of course beneficial to
store the result of log_e(10) so that the conversion is simply a divide.

As for the antilog, and everything else I know, I got that out of some
1960's math book I found in a library somewhere. (It seems like they
stopped making good books around 1984 or so, so if you want any real
information you have to skip the book store and head straight to the
library.) "Mathmematics for Computer Technology" by Paul Carter. It goes
like this:

b^x = 1 + x * ln(b) + (x*ln(b))^2/2! + (x*ln(b))^3/3! ...and so on and so
on...

ln(x) is of course log_e(x)

2! is 2, 3! is 6, 4! is 24, 5! is 120, 6! is 720, etc...

I have another formula written for ln(x). For it you first calculate a =
(x-1)/(x+1), then you calculate ln(x) = 2a + (2*a^3)/3 + (2*a^5)/5
+ (2*a^7)/7 ...and so on.

Naturally, with all of this, it might be nice to calculate e. e = 2
+ 1/2! + 1/3! + 1/4! ...and so on.

The e^x antilog is a bit easier. e^x = 1 + x + x^2/2! + x^3/3! + x^4/4!
....and so on.

> I know how to convert ascii to float or double using maths co-processor
> but do not know how to do conversion WITHOUT using maths coprocessor.

I myself just do everything in integers, using fixed-point math when I
need fractions. If I really want floating point I use the FPU, because I
don't believe I'm going to do it faster than it will.

I never touch a finger to the floating point numbers. I use fild to load
numbers and fist to store them. Were I to do something as silly as use
the FPU to calculate sales tax, I'd store the dollar amounts as a count of
pennies, so that 100 equaled $1, and when loading it into the FPU, just
divide by 100 after it's loaded, and multiply by 100 before storing back
to memory.

I'm of the opinion that floating point shouldn't be used for anything that
isn't scientific. Anything that can be done with fixed point math or
integers should be done with fixed point math or integers. In particular
I want to scream every time my FTP program tells me that it transfered a
file at 3.52312553E+3 KB/s.

> Please tell me how to do these things in assembly language. Are there
> any good sites for mathematics using assembly language ?

None that I'm aware of. (except for mathworld, but it's just math in
general, not specific to assembly language)

Anyway, while you're at it, you might like to know how to calculate the
1.483'th root of 4.145. That's just antilog( 1/1.483 * log(4.145) ),
where of course the base of the log can be whatever is convienent, which
will of course be e.

Then there's sine, cosine, and arctangent.

sin(x) = x - x^3/3! + x^5/5! - x^7/7! + x^9/9! - x^11/11! ...and so on.
cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! - x^10/10! ...and so on.
atan(x) = x - x^3/3 + x^5/5 - x^7/7 + x^9/9 - x^11/11 ... and so on.

The atan formula has the restriction that x has to be between -1 and 1, so
for example to calculate atan(2) you have to calculate arctan(0.5) and
then fudge the result. Not nearly as joyful as the FPU's atan2
instruction.

Now what I don't know how to do is calculate pi.
From: Evenbit on

Richard Cooper wrote:
> Now what I don't know how to do is calculate pi.

This will get you close enough:

2378.9396/757.24

Nathan.

From: ararghmail510NOSPAM on
On Sat, 08 Oct 2005 03:06:35 GMT, "Richard Cooper"
<spamandviruses(a)rr.com> wrote:

<snip>
>Now what I don't know how to do is calculate pi.

ATN(1) * 4

Is what I usually use.


Also: pi/4 = 1 - 1/3 + 1/5 - 1/7 + ....

Which is a reduction of the atan routine, I think.

In QBasic something like (doesn't converge all that fast):

DEFDBL A-Z

p = 1
FOR n = 3 TO 9999999 STEP 4
p = p - (1# / n)
p = p + (1# / (n + 2#))
PRINT n, p * 4#
NEXT n

' this is for reference:
PRINT , ATN(1#) * 4#



--
ArarghMail510 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html

To reply by email, remove the garbage from the reply address.
From: Evenbit on

ararghmail510NOSPAM(a)NOW.AT.arargh.com wrote:
[snip]
> In QBasic something like (doesn't converge all that fast):
>
> DEFDBL A-Z
>
> p = 1
> FOR n = 3 TO 9999999 STEP 4
> p = p - (1# / n)
> p = p + (1# / (n + 2#))
> PRINT n, p * 4#
> NEXT n
>
> ' this is for reference:
> PRINT , ATN(1#) * 4#

Dang!! Is that some new-fangled Super-Extra-High Level Assembler you
are using there??? I can't tell from the syntax which registers you
are using, how many jumps you are making, or which flags you are
testing. :)

Nathan.

 |  Next  |  Last
Pages: 1 2 3 4 5 6 7
Prev: HLA wont compile!!
Next: Structs in Assembly