Link to home
Start Free TrialLog in
Avatar of TrEaSoN
TrEaSoN

asked on

Math (URGENT!)

Dear Experts,
    I need to create a function that can return the sin, cos, tan, and square root of a number.  This number will be extremely large and will be passed as a string due to the size of the number.  Any help would be appreciated.  Thanks!

ASKER CERTIFIED SOLUTION
Avatar of pear49
pear49

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of TrEaSoN
TrEaSoN

ASKER

I see what your getting at...but by not having this math yet (i'm reletivly young) it is very hard to translate into actual source code.  Could you possibly give me a start so I have something to model off of?
Below is something hastily cooked up to do string arithmetic, but is in QBasic:

CLS
a$ = "1019"
b$ = "1093"
c$ = ""
i = 1

IF LEN(a$) > LEN(b$) THEN length = LEN(a$) ELSE length = LEN(b$)
FOR j = 1 TO length - LEN(a$) - length MOD 4 + 4
a$ = "0" + a$
NEXT j
FOR j = 1 TO length - LEN(b$) - length MOD 4 + 4
  b$ = "0" + b$
NEXT j
PRINT a$
PRINT b$

WHILE i < length - length MOD 4 + 4
  result = VAL(MID$(a$, i, 4)) + VAL(MID$(b$, i, 4)) + carry
  IF result > 9999 THEN
    carry = 1
    result = result - 10000
  END IF
  c$ = c$ + LTRIM$(STR$(result))
  i = i + 4
WEND

PRINT c$

============End Code===========
a$ and b$ contains the two string to be added
we extract 4 digits each time and use QBasic's inline addition code to add them, then convert them back to string. repeat until we had process all the digits. Multiplication can be done in a similar way.

You don't need to know the maths. You need to know
n! = n * (n-1) * (n-2) * ... * 3 * 2 * 1
Then you just substitute in...
sub sin(x)
  y = x + (x*x*x)/(3*2*1) + (x*x*x*x*x)/(5*4*3*2*1)
Remember x is in radians, that is 60 degrees is 60/180 * pi. That means 1 pi = 180 degrees. To convert the angle from degree to radians:
radians = degree/180 * pi

Pear
end sub
I already have functions written to handle string addition, subtraction, multiplication and division. They may not be perfect but they are available (free, though point donations would be accepted! ;-)). The first three run pretty fast, but the last (Divide) is kinda slow.

Let me know!
This is an example in QBasic (quickly coded...So the elegance is not there):

DECLARE FUNCTION usin! (x!)
DECLARE FUNCTION ucos! (x!)
DECLARE FUNCTION utan! (x!)
DECLARE FUNCTION fac! (x!)
a = 3.14159 / 4

PRINT "sin a = ", usin(a)
PRINT "cos a = ", ucos(a)
PRINT "tan a = ", utan(a)

FUNCTION fac (x)
 y = 1
 FOR i = 1 TO x
 y = y * i
 NEXT i
 fac = y
END FUNCTION

FUNCTION ucos (x)
  y = 0
  i = 0
  DO
    z = y
    y = y + x ^ i / (fac(i))
    y = y - x ^ (i + 2) / (fac(i + 2))
    i = i + 4
  LOOP UNTIL y = z
  ucos = y
END FUNCTION

FUNCTION usin (x)
  y = 0
  i = 1
  DO
    z = y
    y = y + x ^ i / (fac(i))
    y = y - x ^ (i + 2) / (fac(i + 2))
    i = i + 4
  LOOP UNTIL y = z
  usin = y
END FUNCTION

FUNCTION utan (x)
  utan = usin(x) / ucos(x)
END FUNCTION

===========End of Code============

It uses normal numbers. You can always convert it for strings.

Pear
One consideration for the sin, cos tan of a large number is to note that if (assuming degrees) you divide by 360 and take the remainder, then the sin of the remainder is the sin of the huge number e.g sin(3600001) = sin(1)

If you use a Taylor series on a huge number then convergence will be very slow (i.e it will take a long time to get an answer)
I looked at the first comment I made, and I would like to point out:
sin(x) = x - x^3/3! + x^5/5! + ...
Sorry for the mistake, it had been reflected on the code I previously posted.
treason: how large will these numbers be? The VB Sin, Cos, Tan and Sqr functions all take doubles. Can't you do a:

Sin(CDbl(strNumberAsString))
'(same with Cos, Tan and Sqr)

or are the numbers so large they fall out of the Double range or you get rounding problems?
I fully agree with deighton. Taking the remainder (modulo) of the number as the input to the sin, cos, etc function will be more efficient.

A point which I failed to emphasize on is that though I propose using Taylor's series for finding the sin, cos, etc. I had failed to mentioned that we cannot use the Taylor's series to find square root (at least directly). Please accept my apologies.

We can instead use another method, Newton Raphson (which by the way is 'derived' from Taylor's series). Below is the code for finding the square root.


' number to square root
y = 2

a = .5 * (y + 1)
IF (a < 1) THEN
  b = 2
ELSE b = .5
END IF

FOR c = 1 TO 100
  a = .5 * (a + y * b)
  t = b * (2 - a * b)
  IF t <= 0 THEN b = b * .5 ELSE b = t
NEXT c

PRINT "Square Root of", y, "is", a

Avatar of TrEaSoN

ASKER

I believe sombody asked how large these numbers will be.  Well, more than the 16 digits that a double supports.  These will be thousands upon thousands of digits long which is why they are being passed as a string.  It would be extremely unefficient if it were to be a truncated variable so hence the string.  Does the supplied code support such a long input string?  Thanks for all the help thus far.  The answer is almost there.  I just need some clarification.  Thanks!
Basically these are code for normal numbers not string numbers. For use with string numbers, instead of

c = a + b

you will have

c = StrAdd(a,b)

and so on...

So if your string arithmetic functions support handling these huge strings, it can be done.

Pear
Can you please do something?
Avatar of TrEaSoN

ASKER

sorry about the wait...it took me a few to adapt it to what i wanted.
well, it's ok. I was just getting a little impatient, but it's ok now.

It really do seem very urgent to you by posting so many copies of the question.