_Title "Math regulator mr test sqr estimating" ' b+ start 2021-06-02 ' divide$ found fix? 2021-06-03 comment in that function
' 2021-06-03 update with new sqrRoot$ Function
' 2021-06-06 fixed divide, subtr and mult, all were trimming lead 0's and messing up decimal settings.
' 2021-06-06 test jack's nInverse2$() on STx # to find 115 terms of Fibannci.
' jack error reported 2021-06-04 confirmed! fixed
'Print mr$(".00000000000000000000000000000000000000000000200000000000000054307978001764", "-", ".000000000000000000000000000000000000000000002")
'Print ".00000000000000000000000000000000000000000000000000000000000054307978001764"
ruler$
= "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + Chr$(10)ruler$ = ruler$ + "0 1 2 3 4 5 6 7 8 9 10 11 12"
' debug tests
'Print mr$("-5", "+", "-2100"), " OK if -2105"
'Print mr$("." + String$(20, "0") + "1", "+", "1" + String$(40, "0") + "1") ' first real test of add
'Print ruler$
'Print Val("." + String$(20, "0") + "1") + Val("1" + String$(40, "0") + "1") ' test print of big and small val
'Print mr$("-.00071", "+", ".00036" + String$(35, "0") + "9")
'-.00071
' .00036000000000000000000000000000000000009
'Print "-.00034999999999999999999999999999999999991"
'Print ruler$
'testing a different subtract sub
'Print mr$("10", "-", "5"), " 5 OK"
'Print mr$("-10", "+", "5"), " -5 OK"
'Print mr$("-10", "-", "-5"), " -5 OK"
'Print mr$("-10", "-", "5"), " -15 OK added"
'Print mr$("10", "-", "-5"), " 15 OK added"
'Print mr$("-.010", "-", "-5"), "4.99 OK"
'Print mr$("-.010", "-", "5"), "-5.01 OK just added"
'Print mr$(".010", "-", "5"), " -4.99 OK"
' jack error reported 2021-06-04 confirmed! variation below
'r$ = mr$(".00000000200000000000000054307978001764", "-", ".0000000020000000000000001") '16 0 wrong 8 wrong
'Print " mr$ rtnd:"; r$
'Print " compare:.00000000000000000000000044307978001764" ' 2021-06-05 finally!
' .0000000020000000000000001
' .00000000200000000000000054307978001764
'r$ = mr$(".00000000000000000100000000000000000011", "-", ".000000000000000001000000000000000001") ' bad too
'Print " mr$ rtnd:"; r$
' ".000000000000000001000000000000000001"
'Print " compare:-.00000000000000000000000000000000000089"
'r$ = mr$(".00000000000000000100000000000000000111", "-", ".000000000000000002000000000000000001")
' ".000000000000000002000000000000000001"
' ".00000000000000000100000000000000000111"
' ".00000000000000000099999999999999999989"
'Print " mr$ rtnd:"; r$
'Print " compare:-.00000000000000000099999999999999999989"
'r$ = mr$(".00000000000000000000000000999", "-", "1")
'-1.00000000000000000000000000000000000000000
' .00000000000000000000000000999
' -.99999999999999999999999999001
'Print " mr$ rtnd:"; r$
'Print " compare:-.99999999999999999999999999001"
'r$ = mr$("1", "+", "-1000000000000000000000000000000000000000")
'Print " mr$ rtnd:"; r$
'1000000000000000000000000000000000000000
'-999999999999999999999999999999999999999
'Print " compare:-999999999999999999999999999999999999999"
' check jack problems with FB translation 2021-06-03 errors must be in FB trans from QB64
'Print Mid$(mr$(" .1", "/", "3"), 1, 100) ' too long?
'Print Mid$(mr$("1.1", "/", "9"), 1, 100)
'Print Mid$(mr$("1.38", "/", "1.2"), 1, 100)
'Print ruler$
' another error reported by jack 2021-06-06 fixed (same problem as subtr$)
Print mr$
("1.000000000000000000000001000000000000000000000001", "*", ".000000000000000000000000000000000000000000000001") Print ".000000000000000000000000000000000000000000000001" Print " 1000000000000000000000001000000000000000000000001" 'Print "checking inverse of 50 = .02 "; nInverse$("50", 20) 'OK .020000... length 20
'Print ruler$
'Print
'Print "zzz... see inverse of STx number now takes close to 30 secs with fixed subtr$() sub,"
'Print "Use to come up in a sneeze! It also looks different way more space on end but still"
'Print "can find 115 Fibonacci terms in it."
'Print " The only difference is I am not trimming leading 0's in subst$() function!"
'Sleep
'Cls
Dim inverseSTx$
, start
, done
'inverseSTx$ = nInverse$("999999999999999999999998999999999999999999999999", 2785) ' wow big delay! 19.52 secs +-
inverseSTx$ = nInverse2$("999999999999999999999998999999999999999999999999", 817)
' 816 in 4.22 secs only 64 terms 817 sigDigits matching in 12.93 secs gets all 115 Fibonacci Terms
done
= Timer(.001) - start
Print "inverseSTx$ length = ";
Len(inverseSTx$
) j
= InStr(inverseSTx$
, ".")inverseSTx$
= Mid$(inverseSTx$
, j
+ 1)j = 1
j = j + 48
'f1$ = "1"
'f2$ = "1"
'startSearch = 1
'termN = 2
'Do
' searchFor$ = mr$(f1$, "+", f2$)
' find = InStr(startSearch, inverseSTx$, searchFor$)
' If find Then
' termN = termN + 1
' Print "Term Number"; termN; " = "; searchFor$; " found at"; find
' f1$ = f2$
' f2$ = searchFor$
' startSearch = find + Len(searchFor$)
' Else
' Print searchFor$; " not found."
' Exit Do
' End If
'Loop
'Print "Inverse time:"; done
'Dim n$, result$
'Do
' 'remember everything is strings
' Input "Enter a number to find it's square root "; n$
' If n$ = "" Then End
' result$ = sqrRoot$(n$)
' Print result$
' Print "Length ="; Len(result$)
' _Delay 2
' result$ = SRbyNR$(n$)
' Print result$
' Print "Length ="; Len(result$)
' Print
'Loop
Dim n$
, guess$
, lastGuess$
, other$
, sum$
, imaginary$
, loopcnt
imaginary$
= "*i": n$
= Mid$(nmbr$
, 2) imaginary$ = "": n$ = nmbr$
guess$ = mr$(n$, "/", "2")
other$ = n$
loopcnt = loopcnt + 1
Print "loop cnt"; loopcnt
If (Mid$(guess$
, 1, 105) = Mid$(lastGuess$
, 1, 105)) Then ' go past 100 matching digits for 100 digit precision sqrRoot$
= Mid$(other$
, 1, 101) + imaginary$
' try other factor for guess$ sometimes it nails answer without all digits lastGuess$ = guess$
sum$ = mr$(guess$, "+", other$)
guess$ = mr$(sum$, "/", "2")
other$ = mr$(n$, "/", guess$)
Function SRbyNR$
(nmbr$
) ' square root by Newton - Ralphson method my interpretation of GeorgeMcGinn
Dim n$
, guess$
, lastGuess$
, dx$
, imaginary$
, other$
, loopcnt
imaginary$
= "*i": n$
= Mid$(nmbr$
, 2) imaginary$ = "": n$ = nmbr$
guess$ = mr$(n$, "/", "2") ' get this going first and then try better starting guess later
loopcnt = loopcnt + 1
Print "loop cnt"; loopcnt
If (Mid$(guess$
, 1, 105) = Mid$(lastGuess$
, 1, 105)) Then ' go past 100 matching digits for 100 digit precision SRbyNR$
= Mid$(other$
, 1, 101) + imaginary$
'dx = (x - A / x) / 2: x = x - dx ' Thanks George
lastGuess$ = guess$
dx$ = mr$(mr$(guess$, "-", mr$(n$, "/", guess$)), "/", "2")
guess$ = mr$(guess$, "-", dx$)
other$ = mr$(n$, "/", guess$) ' try other factor for guess$ sometimes it nails answer without all digits
'jacks nInverse2$ modified from using 7 interations to ending when a certain amount of significant digits match between r's
Function nInverse2$
(n$
, SigDigits
As Long) 'assume decimal at very start of the string of digits returned, no rounding While Mid$(lastR
, 1, SigDigits
) <> Mid$(r
, 1, SigDigits
) ' use to be 7 interations lastR = r
r2 = mr$(n$, "*", r)
r2 = mr$("2", "-", r2)
r = mr$(r, "*", r2)
nInverse2$ = r
Function mr$
(a$
, op$
, b$
) ' catchy? mr$ for math regulator Dim ca$
, cb$
, aSgn$
, bSgn$
, postOp$
, sgn$
op$
= _Trim$(op$
) 'save fixing each time ca$
= _Trim$(a$
): cb$
= _Trim$(b$
) 'make copies in case we change 'strip signs and decimals
aSgn$
= "-": ca$
= Mid$(ca$
, 2) aSgn$ = "": ca$ = ca$
ca$
= Mid$(ca$
, 1, dp
- 1) + Mid$(ca$
, dp
+ 1) adp = 0
bSgn$
= "-": cb$
= Mid$(cb$
, 2) bSgn$ = "": cb$ = cb$
cb$
= Mid$(cb$
, 1, dp
- 1) + Mid$(cb$
, dp
+ 1) bdp = 0
If op$
= "+" Or op$
= "-" Or op$
= "/" Then 'add or subtr even up strings on right of decimal 'even up the right sides of decimals if any
dp = adp + bdp
'now according to signs and op$ call add$ or subtr$
If aSgn$
= bSgn$
Then 'really add postOp$ = aSgn$ + add$(ca$, cb$)
Else 'have a case of subtraction If aSgn$
= "-" Then postOp$
= subtr$
(cb$
, ca$
) Else postOp$
= subtr$
(ca$
, cb$
) If bSgn$
= "-" Then 'really add but switch b sign bSgn$ = ""
postOp$ = subtr$(cb$, ca$)
postOp$ = add$(ca$, cb$)
bSgn$ = "-"
postOp$ = aSgn$ + add$(ca$, cb$)
postOp$ = subtr$(ca$, cb$)
postOp$
= sgn$
+ mult$
(ca$
, cb$
) postOp$
= sgn$
+ divide$
(ca$
, cb$
) 'put dp back
lpop
= Len(postOp$
) ' put decimal back postOp$
= Mid$(postOp$
, 1, lpop
- dp
) + "." + Mid$(postOp$
, lpop
- dp
+ 1) mr$ = trim0$(postOp$)
Function divide$
(n$
, d$
) ' goal here is 100 digits precision not 100 digits past decimal
' aha! found a bug when d$ gets really huge 100 is no where near enough!!!!
' 2021-06-03 fix by adding 100 to len(d$), plus have to go a little past 100 for 100 digit precision
' need to go past 100 for 100 precise digits (not decimal places)
di$
= Mid$(nInverse$
(d$
, Len(d$
) + 200), 2) 'chop off decimal point after ndi$ = mult$(n$, di$)
divide$ = trim0$(ndi$)
Function nInverse$
(n$
, DP
As Integer) 'assume decimal at very start of the string of digits returned, no rounding Dim m$
(1 To 9), si$
, r$
, outstr$
, d$
m$(i) = mult$(si$, n$)
outstr$ = ""
outstr$ = "." 'everything else n > 1 is decimal 8/17
r$ = "10"
outstr$ = outstr$ + "0" ' add 0 to the output string
r$ = r$ + "0"
outstr$ = outstr$ + d$
r$ = subtr$(r$, mult$(d$, n$)) 'r = r -d*n
r$ = r$ + "0" 'add another place
Function mult$
(a$
, b$
) 'assume both positive integers prechecked as all digits strings Dim f18$
, f1$
, t$
, build$
, accum$
' fixed mult$ don't trim lead 0's 2021-06-06
'find the longer number and make it a mult of 18 to take 18 digits at a time from it
f1$ = b$
f1$ = a$
For dp
= Len(f1$
) To 1 Step -1 'dp = digit position of the f1$ build$ = "" 'line builder
co = 0
'now taking 18 digits at a time Thanks Steve McNeill
v18
= Val(Mid$(f18$
, m
* 18 - g
* 18 + 1, 18)) build$
= Mid$(t$
, 2) + build$
accum$ = build$
accum$
= add$
(accum$
, build$
+ String$(Len(f1$
) - dp
, "0")) mult$ = accum$
Function subtr$
(sum$
, minus$
) ' assume both numbers are positive all digits Dim ts$
, tm$
, sign$
, LG$
, sm$
, t$
, result$
'ts$ = TrimLead0$(sum$): tm$ = TrimLead0$(minus$) 'orig with decent square root speed
ts$
= _Trim$(sum$
): tm$
= _Trim$(minus$
) ' fixed subtr$ 2021-06-05 If trim0
(ts$
) = trim0$
(tm$
) Then subtr$
= "0":
Exit Function 'OK proceed with function knowing they are not equal tenE18 = 1000000000000000000 'yes!!! no dang E's
If LTE
(ts$
, tm$
) Then ' which is bigger? minus is bigger sign$ = "-"
sign$ = ""
'now taking 18 digits at a time From Steve I learned we can do more than 1 digit at a time
VB
= Val(Mid$(LG$
, m
* 18 - g
* 18 + 1, 18)) vs
= Val(Mid$(sm$
, m
* 18 - g
* 18 + 1, 18)) p = (m - g) * 18
p = p - 1
result$ = t$ + result$
subtr$ = sign$ + result$
Function add$
(a$
, b$
) 'add 2 positive integers assume a and b are just numbers no spaces or - signs 'first thing is to set a and b numbers to same length and multiple of 18 so can take 18 digits at a time
Dim fa$
, fb$
, t$
, new$
, result$
'now taking 18 digits at a time Thanks Steve McNeill
sa
= Val(Mid$(fa$
, m
* 18 - g
* 18 + 1, 18)) sb
= Val(Mid$(fb$
, m
* 18 - g
* 18 + 1, 18)) result$ = new$ + result$
add$ = result$
' String Math Helpers -----------------------------------------------
'this function needs TrimLead0$(s$) a and b have decimal removed and a and b lengths aligned on right
Function LTE
(a$
, b$
) ' a$ Less Than or Equal b$ comparison of 2 strings ca$ = TrimLead0$(a$): cb$ = TrimLead0(b$)
LTE = -1
LTE = -1
LTE = 0
' ------------------------------------- use these for final display
Function TrimLead0$
(s$
) 'for treating strings as number (pos integers) copys$
= _Trim$(s$
) 'might as well remove spaces too i = 1: find = 0
i = i + 1: find = 1
If copys$
= "" Then TrimLead0$
= "0" Else TrimLead0$
= copys$
copys$
= _Trim$(s$
) 'might as well remove spaces too TrimTail0$ = copys$
i
= Len(copys$
): find
= 0 i = i - 1: find = 1
TrimTail0$
= Mid$(copys$
, 1, dp
- 1) TrimTail0$
= Mid$(copys$
, 1, i
)
cs$ = s$
cs$ = TrimLead0$(cs$)
cs$ = TrimTail0$(cs$)
If si$
= "-" Then trim0$
= si$
+ cs$
Else trim0$
= cs$
' for displaying truncated numbers say to 60 digits
cNum$ = num$ 'since num$ could get changed
showDP$ = num$
d
= Val(Mid$(cNum$
, dp
+ nDP
+ 1, 1)) cNum$ = "0" + cNum$ ' tack on another 0 just in case 9's all the way to left
dp = dp + 1
i = dp + nDP
i = i - 1
cNum$
= Mid$(cNum$
, 1, dp
+ nDP
) 'chop it showDP$ = trim0$(cNum$)
showDP$
= Mid$(cNum$
, 1, dp
+ nDP
)