1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-04 04:50:22 +00:00

Changes to CONST and Math Internals

This commit is contained in:
SteveMcNeill 2018-10-31 07:44:57 -04:00
parent 92c4a15735
commit 687cced581

View file

@ -344,6 +344,8 @@ DIM SHARED ideStartAtLine AS LONG, errorLineInInclude AS LONG
DIM SHARED outputfile_cmd$ DIM SHARED outputfile_cmd$
DIM SHARED compilelog$ DIM SHARED compilelog$
DIM cname(4) AS STRING
'$INCLUDE:'global\IDEsettings.bas' '$INCLUDE:'global\IDEsettings.bas'
CMDLineFile = ParseCMDLineArgs$ CMDLineFile = ParseCMDLineArgs$
@ -1972,10 +1974,6 @@ DO
'DEF... do not change type, the expression is stored in a suitable type 'DEF... do not change type, the expression is stored in a suitable type
'based on its value if type isn't forced/specified 'based on its value if type isn't forced/specified
'convert periods to _046_ 'convert periods to _046_
i2 = INSTR(a$, sp + "." + sp) i2 = INSTR(a$, sp + "." + sp)
IF i2 THEN IF i2 THEN
@ -2098,6 +2096,7 @@ DO
'New Edit by Steve on 02/23/2014 to add support for the new Math functions 'New Edit by Steve on 02/23/2014 to add support for the new Math functions
L = 0: Emergency_Exit = 0 'A counter where if we're inside the same DO-Loop for more than 10,000 times, we assume it's an endless loop that didn't process properly and toss out an error message instead of locking up the program. L = 0: Emergency_Exit = 0 'A counter where if we're inside the same DO-Loop for more than 10,000 times, we assume it's an endless loop that didn't process properly and toss out an error message instead of locking up the program.
DO DO
L = INSTR(L + 1, wholestv$, "=") L = INSTR(L + 1, wholestv$, "=")
@ -2108,8 +2107,58 @@ DO
ELSE ELSE
l2 = l2 - 1 'else we only want to take what's before that comma and see if we can use it l2 = l2 - 1 'else we only want to take what's before that comma and see if we can use it
END IF END IF
temp$ = RTRIM$(LTRIM$(MID$(wholestv$, L + 1, l2 - L))) temp$ = " " + MID$(wholestv$, L + 1, l2 - L) + " "
temp1$ = RTRIM$(LTRIM$(Evaluate_Expression$(temp$)))
FOR i2 = 0 TO constlast
cname(1) = " " + constname(i2) + " "
cname(2) = "(" + constname(i2) + " "
cname(3) = " " + constname(i2) + ")"
cname(4) = "(" + constname(i2) + ")"
DO
found = 0
FOR i3 = 1 TO 4
found = INSTR(UCASE$(temp$), cname(i3))
IF found THEN EXIT FOR
NEXT
IF found THEN
t = consttype(i2)
IF t AND ISSTRING THEN
r$ = conststring(i2)
i4 = _INSTRREV(r$, ",")
r$ = LEFT$(r$, i4 - 1)
ELSE
IF t AND ISFLOAT THEN
r$ = STR$(constfloat(i2))
ELSE
IF t AND ISUNSIGNED THEN r$ = STR$(constuinteger(i2)) ELSE r$ = STR$(constinteger(i2))
END IF
END IF
temp$ = LEFT$(temp$, found) + r$ + MID$(temp$, found + LEN(constname(i2)) + 1)
altered = -1
END IF
LOOP UNTIL found = 0
NEXT
wholestv$ = LEFT$(wholestv$, L) + _TRIM$(temp$) + MID$(wholestv$, l2 + 1)
L = L + 1
END IF
Emergency_Exit = Emergency_Exit + 1
IF Emergency_Exit > 10000 THEN a$ = "CONST ERROR: Endless Loop trying to substitute values.": GOTO errmes
LOOP UNTIL L = 0
L = 0: Emergency_Exit = 0 'A counter where if we're inside the same DO-Loop for more than 10,000 times, we assume it's an endless loop that didn't process properly and toss out an error message instead of locking up the program.
DO
L = INSTR(L + 1, wholestv$, "=")
IF L THEN
l2 = INSTR(L + 1, wholestv$, ",") 'Look for a comma after that
IF l2 = 0 THEN 'If there's no comma, then we're working to the end of the line
l2 = LEN(wholestv$)
ELSE
l2 = l2 - 1 'else we only want to take what's before that comma and see if we can use it
END IF
temp$ = MID$(wholestv$, L + 1, l2 - L)
temp$ = _TRIM$(temp$)
temp1$ = Evaluate_Expression$(temp$)
IF LEFT$(temp1$, 5) <> "ERROR" AND temp$ <> temp1$ THEN IF LEFT$(temp1$, 5) <> "ERROR" AND temp$ <> temp1$ THEN
'The math routine should have did its replacement for us. 'The math routine should have did its replacement for us.
altered = -1 altered = -1
@ -2122,9 +2171,11 @@ DO
Emergency_Exit = Emergency_Exit + 1 Emergency_Exit = Emergency_Exit + 1
IF Emergency_Exit > 10000 THEN a$ = "CONST ERROR: Attempting to process MATH Function caused Endless Loop. Please recheck your math formula.": GOTO errmes IF Emergency_Exit > 10000 THEN a$ = "CONST ERROR: Attempting to process MATH Function caused Endless Loop. Please recheck your math formula.": GOTO errmes
LOOP UNTIL L = 0 LOOP UNTIL L = 0
'End of Math Support Edit
'End of Math Support Edit
' _TITLE "Final:" + wholestv$
'Steve edit to update the CONST with the Math and _RGB functions 'Steve edit to update the CONST with the Math and _RGB functions
IF altered THEN IF altered THEN
altered = 0 altered = 0
@ -23396,7 +23447,7 @@ SUB ParseExpression (exp$)
SELECT CASE MID$(exp$, op + c + 1, 1) SELECT CASE MID$(exp$, op + c + 1, 1)
CASE "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "N": numset = -1 'Valid digit CASE "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "N": numset = -1 'Valid digit
CASE "-" 'We need to check if it's a minus or a negative CASE "-" 'We need to check if it's a minus or a negative
IF OName(OpOn) = "PI" OR numset THEN EXIT DO IF OName(OpOn) = "_PI" OR numset THEN EXIT DO
CASE ELSE 'Not a valid digit, we found our separator CASE ELSE 'Not a valid digit, we found our separator
EXIT DO EXIT DO
END SELECT END SELECT
@ -23454,28 +23505,28 @@ SUB Set_OrderOfOperations
'OName ended up becoming the name of our commands, as I modified things.... Go figure! LOL! 'OName ended up becoming the name of our commands, as I modified things.... Go figure! LOL!
'Constants get evaluated first, with a Priority Level of 1 'Constants get evaluated first, with a Priority Level of 1
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "PI" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_PI"
REDIM _PRESERVE PL(i): PL(i) = 1 REDIM _PRESERVE PL(i): PL(i) = 1
'I'm not certain where exactly percentages should go. They kind of seem like a special case to me. COS10% should be COS.1 I'd think... 'I'm not certain where exactly percentages should go. They kind of seem like a special case to me. COS10% should be COS.1 I'd think...
'I'm putting it here for now, and if anyone knows someplace better for it in our order of operations, let me know. 'I'm putting it here for now, and if anyone knows someplace better for it in our order of operations, let me know.
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "%" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "%"
REDIM _PRESERVE PL(i): PL(i) = 5 REDIM _PRESERVE PL(i): PL(i) = 5
'Then Functions with PL 10 'Then Functions with PL 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCCOS" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ACOS"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCSIN" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ASIN"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCSEC" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ARCSEC"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCCSC" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ARCCSC"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCCOT" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ARCCOT"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SECH" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_SECH"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "CSCH" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_CSCH"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "COTH" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_COTH"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "COS" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "COS"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
@ -23489,17 +23540,17 @@ SUB Set_OrderOfOperations
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ATN" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ATN"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "D2R" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_D2R"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "D2G" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_D2G"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "R2D" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_R2D"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "R2G" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_R2G"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "G2D" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_G2D"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "G2R" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_G2R"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ABS" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ABS"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
@ -23511,12 +23562,17 @@ SUB Set_OrderOfOperations
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "FIX" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "FIX"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SEC" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_SEC"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "CSC" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_CSC"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "COT" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_COT"
REDIM _PRESERVE PL(i): PL(i) = 10 REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ASC"
REDIM _PRESERVE PL(i): PL(i) = 10
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "CHR$"
REDIM _PRESERVE PL(i): PL(i) = 10
'Exponents with PL 20 'Exponents with PL 20
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "^" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "^"
REDIM _PRESERVE PL(i): PL(i) = 20 REDIM _PRESERVE PL(i): PL(i) = 20
@ -23529,8 +23585,6 @@ SUB Set_OrderOfOperations
REDIM _PRESERVE PL(i): PL(i) = 30 REDIM _PRESERVE PL(i): PL(i) = 30
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "/" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "/"
REDIM _PRESERVE PL(i): PL(i) = 30 REDIM _PRESERVE PL(i): PL(i) = 30
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "BTM"
REDIM _PRESERVE PL(i): PL(i) = 30
'Integer Division PL 40 'Integer Division PL 40
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "\" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "\"
REDIM _PRESERVE PL(i): PL(i) = 40 REDIM _PRESERVE PL(i): PL(i) = 40
@ -23542,10 +23596,6 @@ SUB Set_OrderOfOperations
REDIM _PRESERVE PL(i): PL(i) = 60 REDIM _PRESERVE PL(i): PL(i) = 60
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "-" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "-"
REDIM _PRESERVE PL(i): PL(i) = 60 REDIM _PRESERVE PL(i): PL(i) = 60
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "BTA"
REDIM _PRESERVE PL(i): PL(i) = 60
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "BTS"
REDIM _PRESERVE PL(i): PL(i) = 60
'Relational Operators =, >, <, <>, <=, >= PL 70 'Relational Operators =, >, <, <>, <=, >= PL 70
i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "<>" i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "<>"
@ -23585,164 +23635,49 @@ END SUB
FUNCTION EvaluateNumbers$ (p, num() AS STRING) FUNCTION EvaluateNumbers$ (p, num() AS STRING)
DIM n1 AS _FLOAT, n2 AS _FLOAT, n3 AS _FLOAT DIM n1 AS _FLOAT, n2 AS _FLOAT, n3 AS _FLOAT
SELECT CASE OName(p) 'Depending on our operator.. SELECT CASE OName(p) 'Depending on our operator..
CASE "PI" CASE "_PI": n1 = 3.14159265358979323846264338327950288## 'Future compatable in case something ever stores extra digits for PI
n1 = 3.14159265358979323846264338327950288## 'Future compatable in case something ever stores extra digits for PI CASE "%": n1 = (VAL(num(1))) / 100 'Note percent is a special case and works with the number BEFORE the % command and not after
CASE "%" 'Note percent is a special case and works with the number BEFORE the % command and not after CASE "_ACOS": n1 = _ACOS(VAL(num(2)))
IF num(1) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get percent of NULL string": EXIT FUNCTION CASE "_ASIN": n1 = _ASIN(VAL(num(2)))
n1 = (VAL(num(1))) / 100 CASE "_ARCSEC": n1 = _ARCSEC(VAL(num(2)))
CASE "ARCCOS" CASE "_ARCCSC": n1 = _ARCCSC(VAL(num(2)))
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCOS of NULL string": EXIT FUNCTION CASE "_ARCCOT": n1 = _ARCCOT(VAL(num(2)))
n1 = VAL(num(2)) CASE "_SECH": n1 = _SECH(VAL(num(2)))
IF n1 > 1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCOS from value >1, which is Invalid": EXIT FUNCTION CASE "_CSCH": n1 = _CSCH(VAL(num(2)))
IF n1 < -1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCOS from value <-1, which is Invalid": EXIT FUNCTION CASE "_COTH": n1 = _COTH(VAL(num(2)))
IF n1 = 1 THEN EvaluateNumbers$ = "0": EXIT FUNCTION CASE "COS": n1 = COS(VAL(num(2)))
n1 = (2 * ATN(1)) - ATN(n1 / SQR(1 - n1 * n1)) CASE "SIN": n1 = SIN(VAL(num(2)))
CASE "ARCSIN" CASE "TAN": n1 = TAN(VAL(num(2)))
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSIN of NULL string": EXIT FUNCTION CASE "LOG": n1 = LOG(VAL(num(2)))
n1 = VAL(num(2)) CASE "EXP": n1 = EXP(VAL(num(2)))
IF n1 > 1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSIN from value >1, which is Invalid": EXIT FUNCTION CASE "ATN": n1 = ATN(VAL(num(2)))
IF n1 < -1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSIN from value <-1, which is Invalid": EXIT FUNCTION CASE "_D2R": n1 = 0.0174532925 * (VAL(num(2)))
n1 = ATN(n1 / SQR(1 - (n1 * n1))) CASE "_D2G": n1 = 1.1111111111 * (VAL(num(2)))
CASE "ARCSEC" CASE "_R2D": n1 = 57.2957795 * (VAL(num(2)))
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSEC of NULL string": EXIT FUNCTION CASE "_R2G": n1 = 0.015707963 * (VAL(num(2)))
n1 = VAL(num(2)) CASE "_G2D": n1 = 0.9 * (VAL(num(2)))
IF n1 > 1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSEC from value > 1, which is Invalid": EXIT FUNCTION CASE "_G2R": n1 = 63.661977237 * (VAL(num(2)))
IF n1 < -1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSEC from value < -1, which is Invalid": EXIT FUNCTION CASE "ABS": n1 = ABS(VAL(num(2)))
n1 = ATN(n1 / SQR(1 - n1 * n1)) + (SGN(n1) - 1) * (2 * ATN(1)) CASE "SGN": n1 = SGN(VAL(num(2)))
CASE "ARCCSC" CASE "INT": n1 = INT(VAL(num(2)))
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCSC of NULL string": EXIT FUNCTION CASE "_ROUND": n1 = _ROUND(VAL(num(2)))
n1 = VAL(num(2)) CASE "FIX": n1 = FIX(VAL(num(2)))
IF n1 > 1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCSC from value >=1, which is Invalid": EXIT FUNCTION CASE "_SEC": n1 = _SEC(VAL(num(2)))
IF n1 < -1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCSC from value <-1, which is Invalid": EXIT FUNCTION CASE "_CSC": n1 = _CSC(VAL(num(2)))
n1 = ATN(1 / SQR(1 - n1 * n1)) + (SGN(n1) - 1) * (2 * ATN(1)) CASE "_COT": n1 = _COT(VAL(num(2)))
CASE "ARCCOT" CASE "^": n1 = VAL(num(1)) ^ VAL(num(2))
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCOT of NULL string": EXIT FUNCTION CASE "SQR": n1 = SQR(VAL(num(2)))
n1 = VAL(num(2))
n1 = (2 * ATN(1)) - ATN(n1)
CASE "SECH"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SECH of NULL string": EXIT FUNCTION
n1 = VAL(num(2))
IF n1 > 88.02969 OR (EXP(n1) + EXP(-n1)) = 0 THEN EvaluateNumbers$ = "ERROR - Bad SECH command": EXIT FUNCTION
n1 = 2 / (EXP(n1) + EXP(-n1))
CASE "CSCH"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get CSCH of NULL string": EXIT FUNCTION
n1 = VAL(num(2))
IF n1 > 88.02969 OR (EXP(n1) - EXP(-n1)) = 0 THEN EvaluateNumbers$ = "ERROR - Bad CSCH command": EXIT FUNCTION
n1 = 2 / (EXP(n1) - EXP(-n1))
CASE "COTH"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get COTH of NULL string": EXIT FUNCTION
n1 = VAL(num(2))
IF 2 * n1 > 88.02969 OR EXP(2 * n1) - 1 = 0 THEN EvaluateNumbers$ = "ERROR - Bad COTH command": EXIT FUNCTION
n1 = (EXP(2 * n1) + 1) / (EXP(2 * n1) - 1)
CASE "COS"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get COS of NULL string": EXIT FUNCTION
n1 = COS(VAL(num(2)))
CASE "SIN"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SIN of NULL string": EXIT FUNCTION
n1 = SIN(VAL(num(2)))
CASE "TAN"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get TAN of NULL string": EXIT FUNCTION
n1 = TAN(VAL(num(2)))
CASE "LOG"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get LOG of NULL string": EXIT FUNCTION
n1 = LOG(VAL(num(2)))
CASE "EXP"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get EXP of NULL string": EXIT FUNCTION
n1 = EXP(VAL(num(2)))
CASE "ATN"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ATN of NULL string": EXIT FUNCTION
n1 = ATN(VAL(num(2)))
CASE "D2R"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Radian of NULL Degree value": EXIT FUNCTION
n1 = 0.0174532925 * (VAL(num(2)))
CASE "D2G"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Grad of NULL Degree string": EXIT FUNCTION
n1 = 1.1111111111 * (VAL(num(2)))
CASE "R2D"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Degree of NULL Radian string": EXIT FUNCTION
n1 = 57.2957795 * (VAL(num(2)))
CASE "R2G"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Grad of NULL Radian string": EXIT FUNCTION
n1 = 0.015707963 * (VAL(num(2)))
CASE "G2D"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Degree of NULL Gradian string": EXIT FUNCTION
n1 = 0.9 * (VAL(num(2)))
CASE "G2R"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Radian of NULL Grad string": EXIT FUNCTION
n1 = 63.661977237 * (VAL(num(2)))
CASE "ABS"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ABS of NULL string": EXIT FUNCTION
n1 = ABS(VAL(num(2)))
CASE "SGN"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SGN of NULL string": EXIT FUNCTION
n1 = SGN(VAL(num(2)))
CASE "INT"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get INT of NULL string": EXIT FUNCTION
n1 = INT(VAL(num(2)))
CASE "_ROUND"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to _ROUND a NULL string": EXIT FUNCTION
n1 = _ROUND(VAL(num(2)))
CASE "FIX"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to FIX a NULL string": EXIT FUNCTION
n1 = FIX(VAL(num(2)))
CASE "SEC"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SEC of NULL string": EXIT FUNCTION
n1 = COS(VAL(num(2)))
IF n1 = 0 THEN EvaluateNumbers$ = "ERROR - COS value is 0, thus SEC is 1/0 which is Invalid": EXIT FUNCTION
n1 = 1 / n1
CASE "CSC"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get CSC of NULL string": EXIT FUNCTION
n1 = SIN(VAL(num(2)))
IF n1 = 0 THEN EvaluateNumbers$ = "ERROR - SIN value is 0, thus CSC is 1/0 which is Invalid": EXIT FUNCTION
n1 = 1 / n1
CASE "COT"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get COT of NULL string": EXIT FUNCTION
n1 = COS(VAL(num(2)))
IF n1 = 0 THEN EvaluateNumbers$ = "ERROR - TAN value is 0, thus COT is 1/0 which is Invalid": EXIT FUNCTION
n1 = 1 / n1
CASE "BTA"
IF num(2) = "" OR num(1) = "" THEN EvaluateNumbers$ = "ERROR - BTA": EXIT FUNCTION
EvaluateNumbers$ = BTen$(num(1), "+", num(2)): EXIT FUNCTION
CASE "BTS"
IF num(2) = "" OR num(1) = "" THEN EvaluateNumbers$ = "ERROR - BTS": EXIT FUNCTION
EvaluateNumbers$ = BTen$(num(1), "-", num(2)): EXIT FUNCTION
CASE "BTM"
IF num(2) = "" OR num(1) = "" THEN EvaluateNumbers$ = "ERROR - BTM": EXIT FUNCTION
EvaluateNumbers$ = BTen$(num(1), "*", num(2)): EXIT FUNCTION
CASE "^"
IF num(1) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to raise NULL string to exponent": EXIT FUNCTION
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to raise number to NULL exponent": EXIT FUNCTION
n1 = VAL(num(1)) ^ VAL(num(2))
CASE "SQR"
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SQR of NULL string": EXIT FUNCTION
IF VAL(num(2)) < 0 THEN EvaluateNumbers$ = "ERROR - Cannot take take SQR of numbers < 0. I'm a computer, I have a poor imagination.": EXIT FUNCTION
n1 = SQR(VAL(num(2)))
CASE "ROOT" CASE "ROOT"
IF num(1) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ROOT of a NULL string": EXIT FUNCTION
IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get NULL ROOT of a string": EXIT FUNCTION
n1 = VAL(num(1)): n2 = VAL(num(2)) n1 = VAL(num(1)): n2 = VAL(num(2))
IF n2 = 1 THEN EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1))): EXIT FUNCTION IF n2 = 1 THEN EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1))): EXIT FUNCTION
IF n2 = 0 THEN EvaluateNumbers$ = "ERROR - There is no such thing as a 0 ROOT of a number": EXIT FUNCTION
IF n1 < 0 AND n2 MOD 2 = 0 AND n2 > 1 THEN EvaluateNumbers$ = "ERROR - Cannot take take an EVEN ROOT of numbers < 0. I'm a computer, I have a poor imagination.": EXIT FUNCTION
IF n1 < 0 AND n2 >= 1 THEN sign = -1: n1 = -n1 ELSE sign = 1 IF n1 < 0 AND n2 >= 1 THEN sign = -1: n1 = -n1 ELSE sign = 1
n3 = 1## / n2 n3 = 1## / n2
IF n3 <> INT(n3) AND n2 < 1 THEN sign = SGN(n1): n1 = ABS(n1) IF n3 <> INT(n3) AND n2 < 1 THEN sign = SGN(n1): n1 = ABS(n1)
n1 = sign * (n1 ^ n3) n1 = sign * (n1 ^ n3)
CASE "*" CASE "*": n1 = VAL(num(1)) * VAL(num(2))
IF num(1) = "" OR num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to multiply NULL string ": EXIT FUNCTION CASE "/": n1 = VAL(num(1)) / VAL(num(2))
n1 = VAL(num(1)) * VAL(num(2)) CASE "\": n1 = VAL(num(1)) \ VAL(num(2))
CASE "/": CASE "MOD": n1 = VAL(num(1)) MOD VAL(num(2))
IF num(1) = "" OR num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to divide NULL string ": EXIT FUNCTION
IF VAL(num(2)) = 0 THEN EvaluateNumbers$ = "ERROR - Division by 0": EXIT FUNCTION
n1 = VAL(num(1)) / VAL(num(2))
CASE "\"
IF num(1) = "" OR num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to divide NULL string ": EXIT FUNCTION
IF VAL(num(2)) = 0 THEN EvaluateNumbers$ = "ERROR - Division by 0": EXIT FUNCTION
n1 = VAL(num(1)) \ VAL(num(2))
CASE "MOD"
IF num(1) = "" OR num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to MOD with NULL string ": EXIT FUNCTION
IF VAL(num(2)) = 0 THEN EvaluateNumbers$ = "ERROR - Division by 0": EXIT FUNCTION
n1 = VAL(num(1)) MOD VAL(num(2))
CASE "+": n1 = VAL(num(1)) + VAL(num(2)) CASE "+": n1 = VAL(num(1)) + VAL(num(2))
CASE "-": n1 = VAL(num(1)) - VAL(num(2)) CASE "-": n1 = VAL(num(1)) - VAL(num(2))
CASE "=": n1 = VAL(num(1)) = VAL(num(2)) CASE "=": n1 = VAL(num(1)) = VAL(num(2))
@ -23947,590 +23882,6 @@ SUB VerifyString (t$)
LOOP UNTIL j > LEN(t$) LOOP UNTIL j > LEN(t$)
END SUB END SUB
FUNCTION BTen$ (InTop AS STRING, Op AS STRING, InBot AS STRING)
REM $DYNAMIC
InTop = LTRIM$(RTRIM$(InTop))
InBot = LTRIM$(RTRIM$(InBot))
l = INSTR(InTop, "-")
IF l = 0 THEN l = INSTR(InTop, "+")
IF l = 0 THEN InTop = "+" + InTop
l = INSTR(InBot, "-")
IF l = 0 THEN l = INSTR(InBot, "+")
IF l = 0 THEN InBot = "+" + InBot
l = INSTR(InTop, ".")
IF l = 0 THEN InTop = InTop + "."
l = INSTR(InBot, ".")
IF l = 0 THEN InBot = InBot + "."
IF Op$ = "-" THEN
Op$ = "+"
IF MID$(InBot, 1, 1) = "-" THEN MID$(InBot, 1, 1) = "+" ELSE MID$(InBot, 1, 1) = "-"
END IF
TDP& = Check&(10, InTop$)
BDP& = Check&(10, InBot$)
IF TDP& < 0 OR BDP& < 0 THEN EXIT FUNCTION
TSign% = Check&(11, InTop$)
BSign% = Check&(11, InBot$)
' Calculate Array Size
IF Op$ = CHR$(43) OR Op$ = CHR$(45) THEN
' "+" (Add) OR "-" (Subtract)
Temp& = 9
ELSEIF Op$ = CHR$(42) OR Op$ = CHR$(50) THEN
' "*" (Multiply) OR "2" (SQRT Multiply)
Temp& = 7
ELSE
EXIT FUNCTION
END IF
' LSA (Left Side of Array)
LSA& = TDP& - 2
TLS& = LSA& \ Temp&
IF LSA& MOD Temp& > 0 THEN
TLS& = TLS& + 1
DO WHILE (TLPad& + LSA&) MOD Temp& > 0
TLPad& = TLPad& + 1
LOOP
END IF
LSA& = BDP& - 2
BLS& = LSA& \ Temp&
IF LSA& MOD Temp& > 0 THEN
BLS& = BLS& + 1
DO WHILE (BLPad& + LSA&) MOD Temp& > 0
BLPad& = BLPad& + 1
LOOP
END IF
IF TLS& >= BLS& THEN LSA& = TLS& ELSE LSA& = BLS&
' RSA (Right Side of Array)
RSA& = LEN(InTop$) - TDP&
TRS& = RSA& \ Temp&
IF RSA& MOD Temp& > 0 THEN
TRS& = TRS& + 1
DO WHILE (TRPad& + RSA&) MOD Temp& > 0
TRPad& = TRPad& + 1
LOOP
END IF
RSA& = LEN(InBot$) - BDP&
BRS& = RSA& \ Temp&
IF RSA& MOD Temp& > 0 THEN
BRS& = BRS& + 1
DO WHILE (BRPad& + RSA&) MOD Temp& > 0
BRPad& = BRPad& + 1
LOOP
END IF
IF TRS& >= BRS& THEN RSA& = TRS& ELSE RSA& = BRS&
IF Op$ = CHR$(43) OR Op$ = CHR$(45) THEN
' "+" (Add) OR "-" (Subtract)
DIM Result(1 TO (LSA& + RSA&)) AS LONG
IF (Op$ = CHR$(43) AND TSign% = BSign%) OR (Op$ = CHR$(45) AND TSign% <> BSign%) THEN
' Add Absolute Values and Return Top Sign
' Left Side
FOR I& = 1 TO LSA&
' Top
IF I& <= (LSA& - TLS&) THEN
''' Result(I&) = Result(I&) + 0
ELSEIF I& = (1 + LSA& - TLS&) THEN
Result(I&) = VAL(MID$(InTop$, 2, (9 - TLPad&)))
TDP& = 11 - TLPad&
ELSE
Result(I&) = VAL(MID$(InTop$, TDP&, 9))
TDP& = TDP& + 9
END IF
' Bottom
IF I& <= (LSA& - BLS&) THEN
''' Result(I&) = Result(I&) + 0
ELSEIF I& = (1 + LSA& - BLS&) THEN
Result(I&) = Result(I&) + VAL(MID$(InBot$, 2, (9 - BLPad&)))
BDP& = 11 - BLPad&
ELSE
Result(I&) = Result(I&) + VAL(MID$(InBot$, BDP&, 9))
BDP& = BDP& + 9
END IF
NEXT I&
' Right Side
TDP& = TDP& + 1: BDP& = BDP& + 1
FOR I& = (LSA& + 1) TO (LSA& + RSA&)
' Top
IF I& > (LSA& + TRS&) THEN
''' Result(I&) = Result(I&) + 0
ELSEIF I& = (LSA& + TRS&) THEN
Result(I&) = (10 ^ TRPad&) * VAL(RIGHT$(InTop$, (9 - TRPad&)))
ELSE
Result(I&) = VAL(MID$(InTop$, TDP&, 9))
TDP& = TDP& + 9
END IF
' Bottom
IF I& > (LSA& + BRS&) THEN
''' Result(I&) = Result(I&) + 0
ELSEIF I& = (LSA& + BRS&) THEN
Result(I&) = Result(I&) + (10 ^ BRPad&) * VAL(RIGHT$(InBot$, (9 - BRPad&)))
ELSE
Result(I&) = Result(I&) + VAL(MID$(InBot$, BDP&, 9))
BDP& = BDP& + 9
END IF
NEXT I&
' Carry
FOR I& = (LSA& + RSA&) TO 2 STEP -1
IF Result(I&) >= 1000000000 THEN
Result(I& - 1) = Result(I& - 1) + 1
Result(I&) = Result(I&) - 1000000000
END IF
NEXT I&
' Return Sign
IF TSign% = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45)
ELSE
' Compare Absolute Values
IF TDP& > BDP& THEN
Compare& = 1
ELSEIF TDP& < BDP& THEN
Compare& = -1
ELSE
IF LEN(InTop$) > LEN(InBot$) THEN Compare& = LEN(InBot$) ELSE Compare& = LEN(InTop$)
FOR I& = 2 TO Compare&
IF VAL(MID$(InTop$, I&, 1)) > VAL(MID$(InBot$, I&, 1)) THEN
Compare& = 1
EXIT FOR
ELSEIF VAL(MID$(InTop$, I&, 1)) < VAL(MID$(InBot$, I&, 1)) THEN
Compare& = -1
EXIT FOR
END IF
NEXT I&
IF Compare& > 1 THEN
IF LEN(InTop$) > LEN(InBot$) THEN
Compare& = 1
ELSEIF LEN(InTop$) < LEN(InBot$) THEN
Compare& = -1
ELSE
Compare& = 0
END IF
END IF
END IF
' Conditional Subtraction
IF Compare& = 1 THEN
' Subtract Bottom from Top and Return Top Sign
' Top
Result(1) = VAL(MID$(InTop$, 2, (9 - TLPad&)))
TDP& = 11 - TLPad&
FOR I& = 2 TO LSA&
Result(I&) = VAL(MID$(InTop$, TDP&, 9))
TDP& = TDP& + 9
NEXT I&
TDP& = TDP& + 1
FOR I& = (LSA& + 1) TO (LSA& + TRS& - 1)
Result(I&) = VAL(MID$(InTop$, TDP&, 9))
TDP& = TDP& + 9
NEXT I&
Result(LSA& + TRS&) = 10& ^ TRPad& * VAL(RIGHT$(InTop$, (9 - TRPad&)))
' Bottom
BDP& = (LEN(InBot$) - 17) + BRPad&
FOR I& = (LSA& + BRS&) TO (1 + LSA& - BLS&) STEP -1
IF I& = LSA& THEN BDP& = BDP& - 1
IF I& = (LSA& + BRS&) THEN
Temp& = (10& ^ BRPad&) * VAL(RIGHT$(InBot$, (9 - BRPad&)))
ELSEIF I& = (1 + LSA& - BLS&) THEN
Temp& = VAL(MID$(InBot$, 2, (9 - BLPad&)))
ELSE
Temp& = VAL(MID$(InBot$, BDP&, 9))
BDP& = BDP& - 9
END IF
IF Result(I&) < Temp& THEN
' Borrow
FOR J& = (I& - 1) TO 1 STEP -1
IF Result(J&) = 0 THEN
Result(J&) = 999999999
ELSE
Result(J&) = Result(J&) - 1
EXIT FOR
END IF
NEXT J&
Result(I&) = Result(I&) + 1000000000
END IF
Result(I&) = Result(I&) - Temp&
NEXT I&
' Return Sign
IF TSign% = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45)
ELSEIF Compare& = -1 THEN
' Subtract Top from Bottom and Return Bottom Sign
' Bottom
Result(1) = VAL(MID$(InBot$, 2, (9 - BLPad&)))
BDP& = 11 - BLPad&
FOR I& = 2 TO LSA&
Result(I&) = VAL(MID$(InBot$, BDP&, 9))
BDP& = BDP& + 9
NEXT I&
BDP& = BDP& + 1
FOR I& = (LSA& + 1) TO (LSA& + BRS& - 1)
Result(I&) = VAL(MID$(InBot$, BDP&, 9))
BDP& = BDP& + 9
NEXT I&
Result(LSA& + BRS&) = 10& ^ BRPad& * VAL(RIGHT$(InBot$, (9 - BRPad&)))
' Top
TDP& = (LEN(InTop$) - 17) + TRPad&
FOR I& = (LSA& + TRS&) TO (1 + LSA& - TLS&) STEP -1
IF I& = LSA& THEN TDP& = TDP& - 1
IF I& = (LSA& + TRS&) THEN
Temp& = (10& ^ TRPad&) * VAL(RIGHT$(InTop$, (9 - TRPad&)))
ELSEIF I& = (1 + LSA& - TLS&) THEN
Temp& = VAL(MID$(InTop$, 2, (9 - TLPad&)))
ELSE
Temp& = VAL(MID$(InTop$, TDP&, 9))
TDP& = TDP& - 9
END IF
IF Result(I&) < Temp& THEN
' Borrow
FOR J& = (I& - 1) TO 1 STEP -1
IF Result(J&) = 0 THEN
Result(J&) = 999999999
ELSE
Result(J&) = Result(J&) - 1
EXIT FOR
END IF
NEXT J&
Result(I&) = Result(I&) + 1000000000
END IF
Result(I&) = Result(I&) - Temp&
NEXT I&
' Build Return Sign
IF BSign% = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45)
ELSE
' Result will always be 0
LSA& = 1: RSA& = 1
RetStr$ = CHR$(43)
END IF
END IF
' Generate Return String
RetStr$ = RetStr$ + LTRIM$(STR$(Result(1)))
FOR I& = 2 TO LSA&
RetStr$ = RetStr$ + RIGHT$(STRING$(8, 48) + LTRIM$(STR$(Result(I&))), 9)
NEXT I&
RetStr$ = RetStr$ + CHR$(46)
FOR I& = (LSA& + 1) TO (LSA& + RSA&)
RetStr$ = RetStr$ + RIGHT$(STRING$(8, 48) + LTRIM$(STR$(Result(I&))), 9)
NEXT I&
ERASE Result
ELSEIF Op$ = CHR$(42) THEN
' * (Multiply)
DIM TArray(1 TO (LSA& + RSA&)) AS LONG
DIM BArray(1 TO (LSA& + RSA&)) AS LONG
DIM ResDBL(0 TO (LSA& + RSA&)) AS DOUBLE
' Push String Data Into Array
FOR I& = 1 TO LSA&
IF I& <= (LSA& - TLS&) THEN
''' TArray(I&) = TArray(I&) + 0
ELSEIF I& = (1 + LSA& - TLS&) THEN
TArray(I&) = VAL(MID$(InTop$, 2, (7 - TLPad&)))
TDP& = 9 - TLPad&
ELSE
TArray(I&) = VAL(MID$(InTop$, TDP&, 7))
TDP& = TDP& + 7
END IF
IF I& <= (LSA& - BLS&) THEN
''' BArray(I&) = BArray(I&) + 0
ELSEIF I& = (1 + LSA& - BLS&) THEN
BArray(I&) = VAL(MID$(InBot$, 2, (7 - BLPad&)))
BDP& = 9 - BLPad&
ELSE
BArray(I&) = VAL(MID$(InBot$, BDP&, 7))
BDP& = BDP& + 7
END IF
NEXT I&
TDP& = TDP& + 1: BDP& = BDP& + 1
FOR I& = (LSA& + 1) TO (LSA& + RSA&)
IF I& > (LSA& + TRS&) THEN
''' TArray(I&) = TArray(I&) + 0
ELSEIF I& = (LSA& + TRS&) THEN
TArray(I&) = 10 ^ TRPad& * VAL(RIGHT$(InTop$, (7 - TRPad&)))
ELSE
TArray(I&) = VAL(MID$(InTop$, TDP&, 7))
TDP& = TDP& + 7
END IF
IF I& > (LSA& + BRS&) THEN
''' BArray(I&) = BArray(I&) + 0
ELSEIF I& = (LSA& + BRS&) THEN
BArray(I&) = 10 ^ BRPad& * VAL(RIGHT$(InBot$, (7 - BRPad&)))
ELSE
BArray(I&) = VAL(MID$(InBot$, BDP&, 7))
BDP& = BDP& + 7
END IF
NEXT I&
' Multiply from Arrays to Array
FOR I& = (LSA& + TRS&) TO (1 + LSA& - TLS&) STEP -1
FOR J& = (LSA& + BRS&) TO (1 + LSA& - BLS&) STEP -1
Temp# = 1# * TArray(I&) * BArray(J&)
IF (I& + J&) MOD 2 = 0 THEN
TL& = INT(Temp# / 10000000)
TR& = Temp# - 10000000# * TL&
ResDBL(((I& + J&) \ 2) - 1) = ResDBL(((I& + J&) \ 2) - 1) + TL&
ResDBL((I& + J&) \ 2) = ResDBL((I& + J&) \ 2) + 10000000# * TR&
ELSE
ResDBL((I& + J&) \ 2) = ResDBL((I& + J&) \ 2) + Temp#
END IF
IF ResDBL((I& + J&) \ 2) >= 100000000000000# THEN
Temp# = ResDBL((I& + J&) \ 2)
TL& = INT(Temp# / 100000000000000#)
ResDBL(((I& + J&) \ 2) - 1) = ResDBL(((I& + J&) \ 2) - 1) + TL&
ResDBL((I& + J&) \ 2) = Temp# - 100000000000000# * TL&
END IF
NEXT J&
NEXT I&
ERASE TArray, BArray
' Generate Return String
IF (TSign% * BSign%) = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45)
RetStr$ = RetStr$ + LTRIM$(STR$(ResDBL(0)))
FOR I& = 1 TO (LSA&)
RetStr$ = RetStr$ + RIGHT$(STRING$(13, 48) + LTRIM$(STR$(ResDBL(I&))), 14)
NEXT I&
RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 7) + CHR$(46) + RIGHT$(RetStr$, 7)
FOR I& = (LSA& + 1) TO (LSA& + RSA&)
RetStr$ = RetStr$ + RIGHT$(STRING$(13, 48) + LTRIM$(STR$(ResDBL(I&))), 14)
NEXT I&
ERASE ResDBL
ELSEIF Op$ = CHR$(50) THEN
' 2 (SQRT Multiply)
DIM IArray(1 TO (LSA& + RSA&)) AS LONG
DIM ResDBL(0 TO (LSA& + RSA&)) AS DOUBLE
' Push String Data Into Array
FOR I& = 1 TO LSA&
IF I& <= (LSA& - TLS&) THEN
''' IArray(I&) = IArray(I&) + 0
ELSEIF I& = (1 + LSA& - TLS&) THEN
IArray(I&) = VAL(MID$(InTop$, 2, (7 - TLPad&)))
TDP& = 9 - TLPad&
ELSE
IArray(I&) = VAL(MID$(InTop$, TDP&, 7))
TDP& = TDP& + 7
END IF
NEXT I&
TDP& = TDP& + 1
FOR I& = (LSA& + 1) TO (LSA& + RSA&)
IF I& > (LSA& + TRS&) THEN
''' IArray(I&) = IArray(I&) + 0
ELSEIF I& = (LSA& + TRS&) THEN
IArray(I&) = 10 ^ TRPad& * VAL(RIGHT$(InTop$, (7 - TRPad&)))
ELSE
IArray(I&) = VAL(MID$(InTop$, TDP&, 7))
TDP& = TDP& + 7
END IF
NEXT I&
' SQRT Multiply from Array to Array
FOR I& = (LSA& + TRS&) TO 1 STEP -1
FOR J& = I& TO 1 STEP -1
Temp# = 1# * IArray(I&) * IArray(J&)
IF I& <> J& THEN Temp# = Temp# * 2
IF (I& + J&) MOD 2 = 0 THEN
TL& = INT(Temp# / 10000000)
TR& = Temp# - 10000000# * TL&
ResDBL(((I& + J&) \ 2) - 1) = ResDBL(((I& + J&) \ 2) - 1) + TL&
ResDBL((I& + J&) \ 2) = ResDBL((I& + J&) \ 2) + 10000000# * TR&
ELSE
ResDBL((I& + J&) \ 2) = ResDBL((I& + J&) \ 2) + Temp#
END IF
IF ResDBL((I& + J&) \ 2) >= 100000000000000# THEN
Temp# = ResDBL((I& + J&) \ 2)
TL& = INT(Temp# / 100000000000000#)
ResDBL(((I& + J&) \ 2) - 1) = ResDBL(((I& + J&) \ 2) - 1) + TL&
ResDBL((I& + J&) \ 2) = Temp# - 100000000000000# * TL&
END IF
NEXT J&
NEXT I&
ERASE IArray
' Generate Return String
IF (TSign% * BSign%) = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45)
RetStr$ = RetStr$ + LTRIM$(STR$(ResDBL(0)))
FOR I& = 1 TO (LSA&)
RetStr$ = RetStr$ + RIGHT$(STRING$(13, 48) + LTRIM$(STR$(ResDBL(I&))), 14)
NEXT I&
RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 7) + CHR$(46) + RIGHT$(RetStr$, 7)
' Don't usually want the full right side for this, just enough to check the
' actual result against the expected result, which is probably an integer.
' Uncomment the three lines below when trying to find an oddball square root.
'FOR I& = (LSA& + 1) TO (LSA& + RSA&)
' RetStr$ = RetStr$ + RIGHT$(STRING$(13, 48) + LTRIM$(STR$(ResDBL(I&))), 14)
'NEXT I&
ERASE ResDBL
END IF
' Trim Leading and Trailing Zeroes
DO WHILE MID$(RetStr$, 2, 1) = CHR$(48) AND MID$(RetStr$, 3, 1) <> CHR$(46)
RetStr$ = LEFT$(RetStr$, 1) + RIGHT$(RetStr$, LEN(RetStr$) - 2)
LOOP
DO WHILE RIGHT$(RetStr$, 1) = CHR$(48) AND RIGHT$(RetStr$, 2) <> CHR$(46) + CHR$(48)
RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 1)
LOOP
IF MID$(RetStr$, 1, 1) = "+" THEN MID$(RetStr$, 1, 1) = " "
DO
r$ = RIGHT$(RetStr$, 1)
IF r$ = "0" THEN RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 1)
LOOP UNTIL r$ <> "0"
r$ = RIGHT$(RetStr$, 1)
IF r$ = "." THEN RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 1)
BTen$ = RetStr$
END FUNCTION
REM $STATIC
' ---------------------------------------------------------------------------
' FUNCTION Check& (Op&, InString$) Multi-Purpose String Tester
' ---------------------------------------------------------------------------
'
' * Op& = Type of string to expect and/or operation to perform
'
' { 00A } = (10) Test Base-10-Format String ( *!* ALTERS InString$ *!* )
' { 00B } = (11) Read Sign ("+", "-", or CHR$(241))
'
' Unlisted values are not used and will return [ Check& = 0 - Op& ].
' Different Op& values produce various return values.
' Refer to the in-code comments for details.
'
' ---------------------------------------------------------------------------
' FUNCTION Check& (Op&, InString$) Multi-Purpose String Tester
' ---------------------------------------------------------------------------
FUNCTION Check& (Op AS LONG, InString AS STRING)
REM $DYNAMIC
RetVal& = LEN(InString$)
SELECT CASE Op&
CASE 10
' {00A} Test String for Base-10-Format ( *!* ALTERS InString$ *!* )
' Returns:
' {& > 0} = DP offset; {& < 0} = FAILED at negative offset
'
' After testing passes, the string is trimmed
' of nonessential leading and trailing zeroes.
IF RetVal& = 0 THEN
RetVal& = -1
ELSE
SELECT CASE ASC(LEFT$(InString$, 1))
CASE 43, 45 ' "+", "-"
FOR I& = 2 TO RetVal&
SELECT CASE ASC(MID$(InString$, I&, 1))
CASE 46 ' "."
IF DPC% > 0 THEN
RetVal& = 0 - I&
EXIT FOR
ELSE
DPC% = DPC% + 1
RetVal& = I&
END IF
CASE 48 TO 57
' keep going
CASE ELSE
RetVal& = 0 - I&
EXIT FOR
END SELECT
NEXT I&
CASE ELSE
RetVal& = -1
END SELECT
IF DPC% = 0 AND RetVal& > 0 THEN
RetVal& = 0 - RetVal&
ELSEIF RetVal& = 2 THEN
InString$ = LEFT$(InString$, 1) + CHR$(48) + RIGHT$(InString$, LEN(InString$) - 1)
RetVal& = RetVal& + 1
END IF
IF RetVal& = LEN(InString$) THEN InString$ = InString$ + CHR$(48)
DO WHILE ASC(RIGHT$(InString$, 1)) = 48 AND RetVal& < (LEN(InString$) - 1)
InString$ = LEFT$(InString$, LEN(InString$) - 1)
LOOP
DO WHILE ASC(MID$(InString$, 2, 1)) = 48 AND RetVal& > 3
InString$ = LEFT$(InString$, 1) + RIGHT$(InString$, LEN(InString$) - 2)
RetVal& = RetVal& - 1
LOOP
END IF
CASE 11
' {00B} Read Sign ("+", "-", or CHR$(241))
' Returns:
' Explicit: +1 = Positive; -1 = Negative; 0 = Unsigned;
' Implied: +64 = Positive; -64 = NULL String
IF RetVal& = 0 THEN RetVal& = -64
FOR I& = 1 TO RetVal&
SELECT CASE ASC(MID$(InString$, I&, 1))
CASE 32
RetVal& = 64
' keep going
CASE 43
RetVal& = 1
EXIT FOR
CASE 45
RetVal& = -1
EXIT FOR
CASE 241
RetVal& = 0
EXIT FOR
CASE ELSE
RetVal& = 64
EXIT FOR
END SELECT
NEXT I&
CASE ELSE
RetVal& = 0 - Op&
END SELECT
Check& = RetVal&
END FUNCTION
FUNCTION N2S$ (exp$) 'scientific Notation to String FUNCTION N2S$ (exp$) 'scientific Notation to String
t$ = LTRIM$(RTRIM$(exp$)) t$ = LTRIM$(RTRIM$(exp$))
IF LEFT$(t$, 1) = "-" THEN sign$ = "-": t$ = MID$(t$, 2) IF LEFT$(t$, 1) = "-" THEN sign$ = "-": t$ = MID$(t$, 2)