Prev: HLA wont compile!!
Next: Structs in Assembly
From: knowledgehungry on 7 Oct 2005 15:01 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 7 Oct 2005 23:06 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 7 Oct 2005 23:57 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 8 Oct 2005 00:26 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 8 Oct 2005 00:51
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. |