### Author Topic: String Math  (Read 3946 times)

0 Members and 1 Guest are viewing this topic.

#### bplus ##### Re: String Math
« Reply #60 on: June 14, 2021, 08:58:55 PM »
Thanks @jack

BTW you mentioned you did not understand my nInverse\$(), as I recall I coded it as I learned to do division in school only we are just dividing into 1 so we are always adding 0's to remainder until big enough to divide some more by denominator and find another set of remainder start digits upon which to add zeros... maybe you figured it out already.

This String Math will have to do until you or George or Luke get a full set of operations going with memory works or with decimal math segments building.

#### david_uwi

• Newbie
• Posts: 74 ##### Re: String Math
« Reply #61 on: June 16, 2021, 02:17:18 PM »
I am always confused when calculation that gives a large number of digits is generally tackled by using strings.
It seems obvious that you could store the digits in an array (rather than a string) which would avoid the VAL and STR\$ which are slow.
Calculating the 115 Fibonacci is trivial even doing it the hard way of going through all the numbers 11235...to get to the 115 number. I've posted it before (but as I'm very proud of it) I will post it again.
Code: QB64: [Select]
1. DIM a(30000) AS INTEGER, b(30000) AS INTEGER
2. DEFLNG F-I
3. DEFINT J-N
4. INPUT "input the fibonacci number to calculate"; fmax
5. tt = TIMER
6. b(1) = 1: n = 1
7. FOR i = 1 TO (fmax + 1) \ 2
8.     FOR j = 1 TO n
9.         b(j) = a(j) + b(j) + jc
10.         IF b(j) > 9999 THEN b(j) = b(j) - 10000: jc = 1 ELSE jc = 0
11.     NEXT j
12.     IF jc = 1 THEN n = n + 1: b(n) = 1: jc = 0
13.     FOR j = 1 TO n
14.         a(j) = a(j) + b(j) + jc
15.         IF a(j) > 9999 THEN a(j) = a(j) - 10000: jc = 1 ELSE jc = 0
16.     NEXT j
17.     IF jc = 1 THEN n = n + 1: a(n) = 1: jc = 0
18. FOR j = n TO 1 STEP -1
19.     IF fmax MOD 2 = 0 THEN
20.         IF j = n THEN t\$ = LTRIM\$(STR\$(a(j))) ELSE t\$ = RIGHT\$("0000" + LTRIM\$(STR\$(a(j))), 4)
21.         PRINT USING "&"; t\$;
22.     IF fmax MOD 2 = 1 THEN
23.         IF j = n THEN t\$ = LTRIM\$(STR\$(b(j))) ELSE t\$ = RIGHT\$("0000" + LTRIM\$(STR\$(b(j))), 4)
24.         PRINT USING "&"; t\$;
25. PRINT: PRINT "number of digits = ";
26. IF fmax MOD 2 = 1 THEN PRINT (n - 1) * 4 + LEN(LTRIM\$(STR\$(a(n))))
27. IF fmax MOD 2 = 0 THEN PRINT (n - 1) * 4 + LEN(LTRIM\$(STR\$(b(n))))
28. PRINT "TIME TAKEN= "; TIMER - tt; "SECONDS"

#### bplus ##### Re: String Math
« Reply #62 on: June 16, 2021, 03:23:14 PM »
I am always confused when calculation that gives a large number of digits is generally tackled by using strings.
It seems obvious that you could store the digits in an array (rather than a string) which would avoid the VAL and STR\$ which are slow.
Calculating the 115 Fibonacci is trivial even doing it the hard way of going through all the numbers 11235...to get to the 115 number. I've posted it before (but as I'm very proud of it) I will post it again.
Code: QB64: [Select]
1. DIM a(30000) AS INTEGER, b(30000) AS INTEGER
2. DEFLNG F-I
3. DEFINT J-N
4. INPUT "input the fibonacci number to calculate"; fmax
5. tt = TIMER
6. b(1) = 1: n = 1
7. FOR i = 1 TO (fmax + 1) \ 2
8.     FOR j = 1 TO n
9.         b(j) = a(j) + b(j) + jc
10.         IF b(j) > 9999 THEN b(j) = b(j) - 10000: jc = 1 ELSE jc = 0
11.     NEXT j
12.     IF jc = 1 THEN n = n + 1: b(n) = 1: jc = 0
13.     FOR j = 1 TO n
14.         a(j) = a(j) + b(j) + jc
15.         IF a(j) > 9999 THEN a(j) = a(j) - 10000: jc = 1 ELSE jc = 0
16.     NEXT j
17.     IF jc = 1 THEN n = n + 1: a(n) = 1: jc = 0
18. FOR j = n TO 1 STEP -1
19.     IF fmax MOD 2 = 0 THEN
20.         IF j = n THEN t\$ = LTRIM\$(STR\$(a(j))) ELSE t\$ = RIGHT\$("0000" + LTRIM\$(STR\$(a(j))), 4)
21.         PRINT USING "&"; t\$;
22.     IF fmax MOD 2 = 1 THEN
23.         IF j = n THEN t\$ = LTRIM\$(STR\$(b(j))) ELSE t\$ = RIGHT\$("0000" + LTRIM\$(STR\$(b(j))), 4)
24.         PRINT USING "&"; t\$;
25. PRINT: PRINT "number of digits = ";
26. IF fmax MOD 2 = 1 THEN PRINT (n - 1) * 4 + LEN(LTRIM\$(STR\$(a(n))))
27. IF fmax MOD 2 = 0 THEN PRINT (n - 1) * 4 + LEN(LTRIM\$(STR\$(b(n))))
28. PRINT "TIME TAKEN= "; TIMER - tt; "SECONDS"

So what do you get for first 10,000 digit Fibonacci?

I get:

#### bplus ##### Re: String Math
« Reply #63 on: June 16, 2021, 03:32:00 PM »
Is fast!

But I never claimed to be faster, just a set of routines in about 412 LOC to extend math beyond Type restrictions of QB64.

Update: for the record, String Math took 21.1692 secs to get to 47,847th term, the first at 10,000 digits.

@david_uwi also for the record we are getting Fibonacci sequence of 115 terms from inverse of STx Number:
"999999999999999999999998999999999999999999999999"
which is so much cooler than merely adding up a bunch of terms.

If you get a whole set of routines in a fair amount of LOC then I will gladly swap out String Math routines in NY minute!

If someone needs something now, here it is, slow as it may be. :)
« Last Edit: June 16, 2021, 03:55:06 PM by bplus »

#### jack ##### Re: String Math
« Reply #64 on: June 16, 2021, 04:42:44 PM »
hi bplus
try the reciprocal of 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
it requires about 38,709 digits and gives 432 Fibo numbers starting with 0
here's pseudo code to produce them
Code: [Select]
`s\$=string\$(89,"9")+"8"+string(90,"9")z\$=nInverse(s\$)j=instr(z\$,".")s\$=mid(z\$,j+1)j=1for i=1 to 432 print mid\$(s,j,90) j=j+90next`

#### bplus ##### Re: String Math
« Reply #65 on: June 16, 2021, 04:46:38 PM »
@jack  cool! thanks :)

Confirmed:
Counting 0 as first, 432 terms found the last starts at 38792. I had to increase my number of decimals to 39000 from what I tried the first time, probably not minimum needed to find the 432 terms. 6.81 mins was the time for last run.
« Last Edit: June 16, 2021, 06:25:28 PM by bplus »

#### jack ##### Re: String Math
« Reply #66 on: June 16, 2021, 07:42:07 PM »
Is fast!
1.7 seconds
that really fast for string math, well done bplus

#### bplus ##### Re: String Math
« Reply #67 on: June 16, 2021, 08:07:40 PM »
that really fast for string math, well done bplus

I wish, that was David's code I was saying his was fast. I did say later post 21 secs for String Math.

I don't think you will catch me initiating time trials with String Math :)

#### jack ##### Re: String Math
« Reply #68 on: June 17, 2021, 03:58:03 PM »
hi bplus
I found this interesting document MULTIPLE-LENGTH DIVISION REVISITED

#### George McGinn

• Forum Regular
• Posts: 146 ##### Re: String Math
« Reply #69 on: June 17, 2021, 10:51:24 PM »
I read this 3 years ago when I came up with my division routine. It isn't exactly like this, but I got my idea from this paper.

@jack (Jack - I haven't forgotten about you, it is just that my finished division code isn't in the program file I have, and I am waiting to see if my friend has a copy. Either way I will send it to you tomorrow. If I have to rewrite the division code, I will at least send you the write up on how I coded it).

hi bplus
I found this interesting document MULTIPLE-LENGTH DIVISION REVISITED
________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)

#### jack ##### Re: String Math
« Reply #70 on: June 17, 2021, 11:02:08 PM »
thank you George

#### jack ##### Re: String Math
« Reply #71 on: June 21, 2021, 10:12:19 AM »
Hi bplus
I am still trying to get motivated to study division but as soon as I spend 1 minute reading I loose interest
anyway, in my decfloat routines I found to my disgust that if you take the reciprocal of a number consisting of a lot of 9's and then take the reciprocal of the resulting number, the convergence is very slow, for example
n\$="99999999999999999999999999999999999999999999999999"
the inverse of that number is ".0000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000001"
in sci notation it's 1.00000000000000000000000000000000000000000000000001 E-50
trying to do a reciprocal on that number to get back the original is not easy as there's no way to get a good first approximation, the Newon-Raphson method will eventually converge but it takes many iterations depending on the precision used
I tried it on your math-regulator and it returns .0000000.... instead of the original number
bplus, please explain how you handle big numbers in your nInverse function
« Last Edit: June 21, 2021, 11:42:08 AM by jack »

#### bplus ##### Re: String Math
« Reply #72 on: June 21, 2021, 05:47:21 PM »
Oh jack did you find another bug!? I will check it out when I get time.

#### jack ##### Re: String Math
« Reply #73 on: June 21, 2021, 07:35:12 PM »
bplus, there was an old-timer that wrote a bignum package in visual basic 3 or there about, his website has vanished but you can still get his programs from the wayback machine https://web.archive.org/web/20200220020034/http://www.rain.org/~mkummel/tbvault.html
the package to get are bnc and bignum, there may be things in his code to learn from, who knows?

#### jack ##### Re: String Math
« Reply #74 on: June 21, 2021, 08:19:16 PM »
hi bplus
I extracted the routines needed to do division from bignum, and it actually works
have not cleaned it up for unnecessary constants or variables
Code: QB64: [Select]
1. 'BIGNUM.BAS v0.n
2. 'Sep-Dec 1996 by Marc Kummel aka Treebeard.
3. 'Contact mkummel@rain.org, http://www.rain.org/~mkummel/
4. ' https://web.archive.org/web/20200220020034/http://www.rain.org/~mkummel/tbvault.html
5.
6. 'Big number arithmetic routines, done with a crypto project in mind.  It's
7. 'an engaging task to work out these algorithms in BASIC, since we know them
8. 'so well on paper.  My aim is to minimize string space; then speed.  Not
9. 'quite "arbitrary precision" since numbers and answer must fit in BASIC
10. 'string space, 64K with PDS far strings, much less for QBasic.  Don't use
11. 'the same string twice in one call!  bMul(s\$,s\$,s\$) should figure s=s*s, but
12. 'it won't work because passed strings are modified (and restored) during the
13. 'call, so use temporary strings or pass by value.  See bModPower() for an
14. 'example.  Can be much optimized, but it works and makes sense.
15. '
16. '---------------------------------------------------------------------------
17.
18. 'useful globals
19. Const false = 0, true = Not false, nada = -1
20. Const zero\$ = "0", one\$ = "1", two\$ = "2", three\$ = "3"
21. Const four\$ = "4", five\$ = "5"
22. Const dp\$ = ".", neg\$ = "-", asc0 = 48
23. Const basechr\$ = "B", basesep\$ = "," 'number bases
24. Const negative = -1, positive = 1 'returned by bComp()
25. Const maxlongdig = 8 'max digits in long var&
26. Const maxsegment = 65536 'memory segment size
27. Const memget = 0, memput = 1, memclr = 2 'memory operations
28. Const maxstack = 10 'stack depth
29. Const maxmem = 14 'memory slots (0-9 + constants)
30. Const pimem = 10, pi2mem = 11, emem = 12 'pi, 2pi, e
31. Const ln10mem = 13, ln2mem = 14 'natural logs of 10 & 2
32.
33. 'useful shared stuff
34. Dim Shared digits%
35. Dim Shared topline%, botline%, topview%, botview%
36. Dim Shared esc\$, null\$, error\$, abort\$
37.
38. 'Trick to give bmem\$() its own 64k segment in PDS (but not QB).
39. 'Watch out for overflows or conflicts with multiple modules.
40. Common bmem\$(), zmem\$(), cname\$()
41. Dim bmem\$(maxmem), zmem\$(1 To maxstack), cname\$(10 To maxmem)
42.
43. esc\$ = Chr\$(27) 'useful strings
44. null\$ = ""
45. error\$ = "error! " 'unhelpful error messages
46. abort\$ = "<abort>"
47. op\$ = "+" 'default action
48. digits% = 100 'digits for division etc
49. bignumpath\$ = null\$ 'path for files (or current dir if null)
50. prmcntfile\$ = "BNPRMCNT.DAT" 'prime count table
51. logfile\$ = "BNLOG.LOG" 'log file
52. ReDim prmcnt&(0) 'stub for prime count table
53.
54. 'useful constants
55. cname\$(pimem) = "ã": bmem\$(pimem) = "3.14159265358979323846264338327"
56. cname\$(pi2mem) = "2ã": bmem\$(pi2mem) = "6.28318530717958647692528676654"
57. cname\$(emem) = "e": bmem\$(emem) = "2.71828182845904523536028747135"
58. cname\$(ln10mem) = "ln(10)": bmem\$(ln10mem) = "2.30258509299404568401799145468"
59. cname\$(ln2mem) = "ln(2)": bmem\$(ln2mem) = ".693147180559945309417232121458"
60.
61. 'screen size and window
62. topline% = 1
63. botline% = 25
64. topview% = topline%
65. botview% = botline% - 2
66.
67. 'screen buffer for ScreenSave() and ScreenRestore()
68. screenbufsize% = 80 * botline% * 2 'screen size, 2 bytes per character
69. Dim screenbuf%(screenbufsize% - 1) 'buffer
70. screenrow% = 1 'cursor row
71. Def Seg = 0 'video segment for mono or color
72. If Peek(&H463) = &HB4 Then screenseg& = &HB000 Else screenseg& = &HB800 'color
73.
74. 'trap ctrl-esc for emergency exit.  Speed and size hog, but useful.
75. KEY 15, Chr\$(4) + Chr\$(1)
76. 'On Key(15) GoSub EventTrap
77. Key(15) On
78.
79. 'start up
80. View Print topview% To botview% 'text window
81. Randomize Timer 'I'll make a better RND() sometime
82. ' LoadPrimeTable                       'prime count table
83. ' ShowHelp                             'something to look at
84.
85. '========================================================================
86. n\$ = "1"
87. m\$ = "99999999999999999999999999999999999999999999999999"
88.
89. r\$ = ""
90. Call bDiv(n\$, m\$, r\$)
91. m\$ = r\$ ' you can't use the destination variable in the source
92. Call bDiv(n\$, m\$, r\$)
93. '========================================================================
94.
95.
96. 's = |s|
97. '
98. Sub bAbs (s\$)
99.     If Left\$(s\$, 1) = neg\$ Then s\$ = Mid\$(s\$, 2)
100.
101. 'return true if s is negative
102. '
103. Function bIsNeg% (s\$)
104.     bIsNeg% = (Left\$(s\$, 1) = neg\$)
105.
106. 'return sign of number (-1 or +1)
107. '
108. Function bSign% (s\$)
109.     If bIsNeg(s\$) Then bSign% = negative Else bSign% = positive
110.
111. 'Strip leading 0s and final "." (but leave something)
112. '
113. Sub bStripZero (s\$)
114.     n% = 1
115.     Do While Mid\$(s\$, n%, 1) = zero\$
116.         n% = n% + 1
117.     If n% > 1 Then s\$ = Mid\$(s\$, n%)
118.     If Right\$(s\$, 1) = dp\$ Then s\$ = Left\$(s\$, Len(s\$) - 1)
119.     If Len(s\$) = 0 Then s\$ = zero\$
120.
121. 'Strip trailing 0s to "." (but leave something)
122. '
123. Sub bStripTail (s\$)
124.     n% = Len(s\$)
125.     Do While Mid\$(s\$, n%, 1) = zero\$
126.         n% = n% - 1
127.         If n% <= 1 Then Exit Do
128.     If n% Then If Mid\$(s\$, n%, 1) = dp\$ Then n% = n% - 1
129.     s\$ = Left\$(s\$, n%)
130.     If Len(s\$) = 0 Then s\$ = zero\$
131.
132. 'Strip s\$ to whole number and base 10 integer logarithm and sign.  Decimal
133. 'point is implied after the first digit, and slog% counts places left or
134. 'right.  bLogPut() reverses the process, and bLogDp() gives info on the
135. 'decimals. Tricky, but it works and simplifies dividing and multipling.
136. 'eg s\$ -> s\$ , slog%
137. '  660 -> 66 ,  2     (6.6 * 10^ 2)    (or 660,2 if zeroflag%=false)
138. '  6.6 -> 66 ,  0     (6.6 * 10^ 0)
139. ' .066 -> 66 , -2     (6.6 * 10^-2)
140. 'bDiv(), bMul(), and bSqr() use this to trim unnecessary zeros and to locate
141. 'decimal point.  These set zeroflag% to trim trailing zeros, but bDivIntMod()
142. 'must set it false in order to figure remainder of division.  A kludge.
143. '
144. Sub bLogGet (s\$, slog%, sign%, zeroflag%)
145.     If Left\$(s\$, 1) = neg\$ Then s\$ = Mid\$(s\$, 2): sign% = negative Else sign% = positive
146.     bStripZero s\$
147.     dpt% = InStr(s\$, dp\$)
148.     Select Case dpt%
149.         Case 0
150.             slog% = Len(s\$) - 1
151.         Case 1
152.             n% = dpt% + 1
153.             Do While Mid\$(s\$, n%, 1) = zero\$
154.                 n% = n% + 1
155.             s\$ = Mid\$(s\$, n%)
156.             slog% = dpt% - n%
157.             s\$ = Left\$(s\$, dpt% - 1) + Mid\$(s\$, dpt% + 1)
158.             slog% = dpt% - 2
159.
160.     'remove trailing 0's if zeroflag%
161.     If zeroflag% Then bStripTail s\$
162.
163.
164. 'Strip a number to "standard form" with no leading or trailing 0s and no
165. 'final "."  All routines should return all arguments in this form.
166. '
167. Sub bClean (s\$)
168.     If Left\$(s\$, 1) = neg\$ Then s\$ = Mid\$(s\$, 2): sign% = true
169.     bStripZero s\$
170.     If InStr(s\$, dp\$) Then bStripTail s\$
171.     If sign% And s\$ <> zero\$ Then s\$ = neg\$ + s\$
172.
173. 'Restore a number from the integer and log figured in bLogGet(). s\$ is taken
174. 'as a number with the decimal after first digit, and decimal is moved slog%
175. 'places left or right, adding 0s as required. Called by bDiv() and bMul().
176. '
177. Sub bLogPut (s\$, slog%, sign%)
178.     last% = Len(s\$)
179.     If Len(s\$) = 0 Or s\$ = zero\$ Then
180.         s\$ = zero\$
181.     ElseIf slog% < 0 Then
182.         s\$ = dp\$ + String\$(-slog% - 1, zero\$) + s\$
183.     ElseIf slog% > last% - 1 Then
184.         s\$ = s\$ + String\$(slog% - last% + 1, zero\$) + dp\$
185.         s\$ = Left\$(s\$, slog% + 1) + dp\$ + Mid\$(s\$, slog% + 2)
186.     bClean s\$
187.     If sign% = negative Then s\$ = neg\$ + s\$
188.
189. 'shift decimal n% digits (minus=left), i.e multiply/divide by 10.
190. '
191. Sub bShift (s\$, n%)
192.     bLogGet s\$, slog%, sign%, false
193.     bLogPut s\$, slog% + n%, sign%
194.
195. 's = -s
196. '
197. Sub bNeg (s\$)
198.     If Left\$(s\$, 1) = neg\$ Then s\$ = Mid\$(s\$, 2) Else s\$ = neg\$ + s\$
199.
200. 'Take whole number and log from bLogGet() and return number of decimal
201. 'places in the expanded number; OR take string and number of decimal points
202. 'desired and return the log.  It works both ways.
203. '
204. Function bLogDp% (s\$, logdp%)
205.     bLogDp% = Len(s\$) - 1 - logdp%
206.
207. 'out = s1 / s2 using fast long-integer algorithm. s2\$ must be <= 8 digits.
208. 's1\$ and s2\$ must be stripped first, no decimals.
209. '
210. Sub bDivLong (s1\$, s2\$, quotient\$, remainder\$)
211.     quotient\$ = null\$
212.     remainder& = 0
213.     divisor& = Val(s2\$)
214.
215.     For i% = 1 To digits%
216.         dividend& = remainder& * 10& + Val(Mid\$(s1\$, i%, 1))
217.         dig% = dividend& \ divisor&
218.         quotient\$ = quotient\$ + Chr\$(asc0 + dig%)
219.         remainder& = dividend& - dig% * divisor&
220.     Next i%
221.
222.     If Len(quotient\$) = 0 Then quotient\$ = zero\$
223.     remainder\$ = LTrim\$(Str\$(remainder&))
224.
225.
226. 'out = s1 / s2 using character algorithm, digit by digit, slow but honest.
227. 's1\$ and s2\$ must be stripped first, no decimals.
228. '
229. Sub bDivChar (s1\$, s2\$, quotient\$, remainder\$)
230.     last1% = Len(s1\$) 'length of the dividend
231.     last2% = Len(s2\$) 'length of the divisor
232.     quotient\$ = null\$
233.     remainder\$ = null\$
234.
235.     For i% = 1 To digits%
236.         'get next digit of dividend or zero\$ if past end
237.         If i% <= last1% Then
238.             dvd\$ = remainder\$ + Mid\$(s1\$, i%, 1)
239.             dvd\$ = remainder\$ + zero\$
240.
241.         'if dividend < divisor then digit%=0 else have to calculate it.
242.         'do fast compare using string operations. see bComp%()
243.         bStripZero dvd\$
244.         ldvd% = Len(dvd\$)
245.         If (ldvd% < last2%) Or ((ldvd% = last2%) And (dvd\$ < s2\$)) Then
246.             'divisor is bigger, so digit is 0, easy!
247.             dig% = 0
248.             remainder\$ = dvd\$
249.
250.             'dividend is bigger, but no more than 9 times bigger.
251.             'subtract divisor until we get remainder less than divisor.
252.             'time hog, average is 5 tries through j% loop.  There's a better way.
253.             For dig% = 1 To 9
254.                 remainder\$ = null\$
255.                 borrow% = 0
256.                 For j% = 0 To ldvd% - 1
257.                     n% = last2% - j%
258.                     If n% < 1 Then n% = 0 Else n% = Val(Mid\$(s2\$, n%, 1))
259.                     n% = Val(Mid\$(dvd\$, ldvd% - j%, 1)) - n% - borrow%
260.                     If n% >= 0 Then borrow% = 0 Else borrow% = 1: n% = n% + 10
261.                     remainder\$ = Chr\$(asc0 + n%) + remainder\$
262.                 Next j%
263.
264.                 'if remainder < divisor then exit
265.                 bStripZero remainder\$
266.                 lrem% = Len(remainder\$)
267.                 If (lrem% < last2%) Or ((lrem% = last2%) And (remainder\$ < s2\$)) Then Exit For
268.
269.                 dvd\$ = remainder\$
270.                 ldvd% = Len(dvd\$)
271.             Next dig%
272.
273.         quotient\$ = quotient\$ + Chr\$(asc0 + dig%)
274.     Next i%
275.
276.
277. 'out = s1 / s2
278. '
279. Sub bDiv (s1\$, s2\$, out\$)
280.
281.     'strip divisor
282.     t\$ = s2\$
283.     bLogGet t\$, slog2%, sign2%, true
284.
285.     'divide by zero?
286.     If t\$ = zero\$ Then
287.         out\$ = error\$
288.
289.         'do powers of 10 with shifts
290.     ElseIf t\$ = one\$ Then
291.         out\$ = s1\$
292.         sign1% = bSign(out\$)
293.         If sign1% = negative Then bAbs out\$
294.         bShift out\$, -slog2%
295.         If sign1% <> sign2% Then bNeg out\$
296.
297.         'the hard way
298.         'strip all
299.         s2\$ = t\$: t\$ = null\$
300.         bLogGet s1\$, slog1%, sign1%, true
301.
302.         'figure decimal point and sign of answer
303.         outlog% = slog1% + bLogDp(s2\$, slog2%)
304.         If sign1% <> sign2% Then outsign% = negative Else outsign% = positive
305.
306.         'bump digits past leading zeros and always show whole quotient
307.         olddigits% = digits%
308.         digits% = digits% + Len(s2\$)
309.         If digits% < outlog% + 1 Then digits% = outlog% + 1
310.
311.         'do it, ignore remainder
312.         If Len(s2\$) <= maxlongdig Then bDivLong s1\$, s2\$, out\$, t\$ Else bDivChar s1\$, s2\$, out\$, t\$
313.
314.         'clean up
315.         bLogPut out\$, outlog%, outsign%
316.         bLogPut s1\$, slog1%, sign1%
317.         bLogPut s2\$, slog2%, sign2%
318.         digits% = olddigits%
319.
320.
« Last Edit: June 21, 2021, 08:24:58 PM by jack »