Welcome, Guest
You have to register before you can post on our site.

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 308
» Latest member: Donaldvem
» Forum threads: 1,741
» Forum posts: 17,901

Full Statistics

Latest Threads
The QB64 IDE shell
Forum: Utilities
Last Post: JasonPag
09-16-2024, 05:37 PM
» Replies: 9
» Views: 764
Importance regarding Ches...
Forum: Utilities
Last Post: JasonPag
09-01-2024, 06:34 PM
» Replies: 0
» Views: 31
Chess and Analysis and En...
Forum: Utilities
Last Post: JasonPag
08-28-2024, 02:37 PM
» Replies: 0
» Views: 32
DAY 009:_PutImage
Forum: Keyword of the Day!
Last Post: grymmjack
09-02-2023, 02:57 PM
» Replies: 54
» Views: 2,034
Fall Banner Contest?
Forum: Site Suggestions
Last Post: grymmjack
08-31-2023, 11:50 PM
» Replies: 36
» Views: 1,261
ColorPicker - Function th...
Forum: Dav
Last Post: Dav
08-31-2023, 11:04 PM
» Replies: 3
» Views: 315
Goals(1) = New Tile()
Forum: Works in Progress
Last Post: RhoSigma
08-31-2023, 09:45 PM
» Replies: 3
» Views: 127
micro(A)v11
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 09:14 PM
» Replies: 90
» Views: 3,589
Updating The Single Most ...
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 09:13 PM
» Replies: 7
» Views: 254
QBJS Image Question
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 05:49 PM
» Replies: 5
» Views: 155

 
  Nasty Directory Delete Function
Posted by: eoredson - 09-14-2022, 05:51 AM - Forum: Utilities - Replies (8)

Find attached the directory delete function.

This is a nasty directory delete function.

It deletes a directory and all subdirectories and files.

It doesn't care what the directory is.

Erik.



Attached Files
.zip   SILENT.ZIP (Size: 2.47 KB / Downloads: 38)
Print this item

  Our 200th user registered today.
Posted by: Pete - 09-14-2022, 01:51 AM - Forum: General Discussion - Replies (19)

That makes this place about half the size of the hussel and bussel busy off the carts QBasic Forum! I swear over there there are days Bob and I can barely wake keep up. Kidding aside, nice to see folks are still finding us here. I think our 200th member is from my old haunt, Italy.

Pete

Print this item

  bug when using _Dest _Console
Posted by: Jack - 09-13-2022, 10:18 PM - Forum: General Discussion - Replies (27)

this works Ok, you are prevented from entering a number that's too large for a long

Code: (Select All)
Dim As Long n
Input "n "; n
Print n
however that's not the case here
Code: (Select All)
$Console:Only
_Dest _Console

Dim As Long n
Input "n "; n
Print n
sample run
Code: (Select All)
n ? 99999999999999999999
999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 999999999

Press any key to continue

Print this item

  decfloat -- again
Posted by: Jack - 09-13-2022, 08:45 PM - Forum: Programs - Replies (40)

Code: (Select All)
_Title "defloat by Jack"
$NoPrefix
$Console:Only
Dest Console

Option Explicit

Const NUMBER_OF_DIGITS = 2000
Const NUM_DIGITS = NUMBER_OF_DIGITS
Const NUM_DWORDS = NUM_DIGITS \ 8
Const BIAS = 1073741824 '2 ^ 30
Const MANTISSA_BYTES = (NUM_DWORDS + 1) * 4

Type decfloat
    As Long sign
    As Unsigned Long exponent
    As String * Mantissa_bytes mantissa
End Type

' Error definitions

Const DIVZ_ERR = 1 'Divide by zero
Const EXPO_ERR = 2 'Exponent overflow error
Const EXPU_ERR = 3 'Exponent underflow error
Dim Shared As decfloat pi_dec, tan_half_num(15), tan_half_den(14)
Call initialize_fp

Dim As decfloat n, m, z1, z2, z3, z4
Dim As String s
Dim As Double t
Dim As Long prec, r

t = Timer(.0001)
n = pi_dec
str2fp m, "1e2000"
fpmul n, n, m, NUMBER_OF_DIGITS
fpnroot m, n, 3, NUMBER_OF_DIGITS
t = Timer(.0001) - t
Print "(Pi * 10^2000) ^ (1/3)"
Print fp2str(m, NUMBER_OF_DIGITS)
Print "elapsed time "; t; " seconds"
Print
'================================================
Input "enter the number digits for output (max 2000) "; prec
If prec = 0 Then prec = 2000
If prec > 2000 Then prec = 2000
If prec < 0 Then prec = 80
s = " "
Print "Please enter a number for root extraction, an empty input will exit"
While s <> ""
    Input "enter number "; s
    If s = "" Then Exit While
    If UCase$(s) = "PI" Then
        n = pi_dec
    Else
        str2fp n, s
    End If

    If n.sign <> 0 Then
        Print "can't handle roots of negative numbers, will make the number positive"
        n.sign = 0
    End If
    Input "enter an Integer root# "; r
    If r = 0 Then
        Print 1
        t = 0
    ElseIf Abs(r) > 9999999 Then
        Print "Absolute value for root# too large"
        Print 1
        t = 0
    Else
        t = Timer(.0001)
        fpnroot m, n, r, prec + 4
        t = Timer(.0001) - t
        Print fp2str(m, prec)
    End If
    Print "elapsed time "; t; " seconds"
Wend
'================================================
'Call str2fp(n, "2")
't = Timer
'Call mp_tan(z, n, NUMBER_OF_DIGITS)
't = Timer - t
'Print fp2str(z, NUMBER_OF_DIGITS)
'Print t
't = Timer
'Call fptan(z, n, NUMBER_OF_DIGITS)
't = Timer - t
'Print fp2str(z, NUMBER_OF_DIGITS)
'Print t

'Print fpfix_is_odd(n)
't = Timer
'Call fpfactorial(z, 10000, NUMBER_OF_DIGITS)
't = Timer - t
'Print "factorial(10000) to "; NUMBER_OF_DIGITS; " digits"
'Print fp2str(z, NUMBER_OF_DIGITS)
'Print
'Print "in "; t; " seconds"
'Print
'Call str2fp(n, "3")
'Call str2fp(m, "9")
't = Timer
'Call fpdiv(z, n, m, NUMBER_OF_DIGITS)
't = Timer - t
'Print "3/9 to "; NUMBER_OF_DIGITS; " digits"
'Print fp2str(z, NUMBER_OF_DIGITS)
'Print
'Print "in "; t; " seconds"
'Print
't = Timer
'Call fpmul(z, z, z, NUMBER_OF_DIGITS)
't = Timer - t
'Print "and square it"
'Print fp2str(z, NUMBER_OF_DIGITS)
'Print
'Call str2fp(n, "2")
't = Timer
'Call fplog(z, n, NUMBER_OF_DIGITS)
't = Timer - t
'Print "ln(2) to "; NUMBER_OF_DIGITS; " digits"
'Print fp2str(z, NUMBER_OF_DIGITS)
'Print
'Print "in "; t; " seconds"
'Print
't = Timer
'Call fpexp(z, z, NUMBER_OF_DIGITS)
't = Timer - t
'Print "and the inverse"
'Print fp2str(z, NUMBER_OF_DIGITS)
'Print
'Print "in "; t; " seconds"
'Call si2fp(n, 3, NUMBER_OF_DIGITS)
'Print
'Print "reciprocal of 3"
't = Timer
'Call fpinv(z, n, NUMBER_OF_DIGITS)
't = Timer - t
'Print fp2str(z, NUMBER_OF_DIGITS)
'Print
'Print "in "; t; " seconds"

Sub fptan_half (result As decfloat, x As decfloat, digits_in As Unsigned Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUMBER_OF_DIGITS Then digits = NUMBER_OF_DIGITS
    Dim As decfloat accum, xx, thn, thd

    Call fpmul(xx, x, x, digits)

    'the folowing is a rational polynomial for tan(x/2) derived from the continued fraction
    '                         x^2
    'tan(x/2) = 2 - -------------------------
    '                           x^2
    '              6 - ----------------------
    '                             x^2
    '                 10 - ------------------
    '                               x^2
    '                     14 - --------------
    '                                 x^2
    '                          18 - ---------
    '                                   x^2
    '                              22 - -----
    '                                   26 - ...

    ' and so on
    '
    'the nice quality of this expansion is that you can calculate sin, cos and tan very easily
    '
    'if y = tan(x/2) then
    '
    '          2*x*y
    'sin(x) = -------
    '         y^2+x^2
    '
    '          y^2-x^2
    'cos(x) = ---------
    '          y^2+x^2
    '
    '          2*x*y
    'tan(x) = -------
    '         y^2-x^2

    Call fpmul(thn, xx, tan_half_num(0), digits)
    Call fpsub(thn, thn, tan_half_num(1), digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(2), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(3), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(4), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(5), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(6), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(7), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(8), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(9), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(10), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(11), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(12), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(13), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(14), thn, digits)
    Call fpmul(thn, thn, xx, digits): Call fpadd(thn, tan_half_num(15), thn, digits)

    Call fpsub(thd, xx, tan_half_den(0), digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(1), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(2), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(3), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(4), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(5), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(6), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(7), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(8), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(9), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(10), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(11), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(12), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(13), thd, digits)
    Call fpmul(thd, thd, xx, digits): Call fpadd(thd, tan_half_den(14), thd, digits)

    Call fpdiv(accum, thn, thd, digits) 'tan(x/2)
    result = accum
End Sub


Sub mp_tan (result As decfloat, x As decfloat, digits_in As Unsigned Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUMBER_OF_DIGITS Then digits = NUMBER_OF_DIGITS
    Dim As decfloat ab, accum, factor, x_2, xx, pi1, pi2, circ, tmp, tmp2, tmp3
    Dim As decfloat half
    Dim As Long limit2, i, sign
    pi1 = pi_dec
    Call fpdiv_si(pi2, pi_dec, 2, digits)

    x_2 = x
    For i = 1 To NUM_DWORDS
        Call set(half.mantissa, i, 0)
    Next
    Call set(half.mantissa, 0, 50000000)
    half.exponent = BIAS
    half.sign = 0

    'calculate the sign of tan(x)
    'if integer part of x/(pi/2) is odd then the sign is negative
    'unless x is negative then the sign is positive
    Call fpdiv(tmp, x, pi2, digits)
    sign = fpfix_is_odd(tmp)

    If sign = 1 Then
        sign = &H8000
    Else
        sign = 0
    End If
    Call fpmul_si(circ, pi1, 2, digits)

    Call fpabs(ab, x)

    If fpcmp(ab, circ, digits) = 1 Then
        '======== centralize ==============
        'floor/ceil to centralize

        Call fpadd(pi1, pi1, pi1, digits) 'got 2*pi
        Call fpdiv(tmp, x_2, pi1, digits)
        tmp2 = tmp
        Call fpfix(tmp, tmp) 'int part
        Call fpsub(tmp, tmp2, tmp, digits) 'frac part
        Call fpmul(tmp, tmp, pi1, digits)
        x_2 = tmp
    End If
    '==================================

    'lm = digits of precision, here's a polynomial fit to get an exstimate for limit2
    'works well for precision from 60 to 10000 digits
    limit2 = 1 + Int(-0.45344993886092585968# + 0.022333002852398072433# * NUM_DIGITS + 5.0461814408333079844D-7 * NUM_DIGITS * NUM_DIGITS - 4.2338453039804235772D-11 * NUM_DIGITS * NUM_DIGITS * NUM_DIGITS)

    Call si2fp(factor, 5, digits)

    For i = 1 To limit2
        Call fpmul_si(factor, factor, 5, digits)
    Next
    'factor=factor^limit2

    Call fpdiv(x_2, x_2, factor, digits) 'x_2=x_2/5^limit2
    Call fptan_half(accum, x_2, digits)
    Call fpmul(xx, x_2, x_2, digits)

    'now convert to sin(x)
    Call fpmul_si(tmp, x_2, 2, digits)
    Call fpmul(tmp, tmp, accum, digits)
    Call fpmul(tmp2, accum, accum, digits)
    Call fpadd(tmp2, tmp2, xx, digits)
    Call fpdiv(accum, tmp, tmp2, digits)

    'multiply the result by 5^limit2

    For i = 1 To limit2 + 1
        Call fpmul(tmp, accum, accum, digits)
        Call fpmul(tmp2, accum, tmp, digits)
        'sin(5*x) = 5 * sin(x) - 20 * sin(x)^3 + 16 * sin(x)^5
        Call fpmul_si(accum, accum, 5, digits)
        Call fpmul_si(tmp3, tmp2, 20, digits)
        Call fpsub(accum, accum, tmp3, digits)
        Call fpmul(tmp, tmp2, tmp, digits)
        Call fpmul_si(tmp3, tmp, 16, digits)
        Call fpadd(accum, accum, tmp3, digits)
    Next i

    Call fpmul(tmp, accum, accum, digits)
    Call si2fp(tmp3, 1, digits)
    Call fpsub(tmp, tmp3, tmp, digits)
    Call fpsqr(tmp, tmp, digits)
    Call fpdiv(tmp, accum, tmp, digits)
    tmp.sign = sign Xor x.sign
    result = tmp
End Sub

Sub set (s$, i&, v~&)
    Mid$(s$, 4 * i& + 1, 4) = MKL$(v~&)
End Sub

Function git~& (s$, i&)
    git = CVL(Mid$(s$, 4 * i& + 1, 4))
End Function

Function fp2str_exp$ (n As decfloat, places As Long)
    Dim As Long i, ex
    Dim As String v, f, ts
    If n.exponent > 0 Then
        ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
    Else
        ex = 0
    End If
    If n.sign Then v = "-" Else v = " "
    ts = Str$(git(n.mantissa, 0))
    ts = Trim$(ts)
    If Len(ts) < 8 Then
        ts = ts + String$(8 - Len(ts), "0")
    End If
    v = v + Left$(ts, 1) + "." + Mid$(ts, 2)
    For i = 1 To NUM_DWORDS - 1
        ts = Str$(git(n.mantissa, i))
        ts = Trim$(ts)
        If Len(ts) < 8 Then
            ts = String$(8 - Len(ts), "0") + ts
        End If
        v = v + ts
    Next
    v = Left$(v, places + 3)
    f = Trim$(Str$(Abs(ex)))
    f = String$(5 - Len(f), "0") + f
    If ex < 0 Then v = v + "E-" Else v = v + "E+"
    v = v + f
    fp2str_exp$ = v
End Function

'long part of num
Sub fpfix (result As decfloat, num As decfloat)
    Dim As decfloat ip
    Dim As Long ex, ex2, j, k

    ex = (num.exponent And &H7FFFFFFF) - BIAS
    If ex < 1 Then
        result = ip: Exit Sub
    End If
    If ex >= (NUM_DIGITS) Then
        result = num: Exit Sub
    End If
    ex2 = ex \ 8
    k = ex2
    j = ex Mod 8
    While ex2 > 0
        ex2 = ex2 - 1
        Call set(ip.mantissa, ex2, git(num.mantissa, ex2))
    Wend
    If j = 1 Then
        Call set(ip.mantissa, k, 10000000 * (git(num.mantissa, k) \ 10000000))
    ElseIf j = 2 Then
        Call set(ip.mantissa, k, 1000000 * (git(num.mantissa, k) \ 1000000))
    ElseIf j = 3 Then
        Call set(ip.mantissa, k, 100000 * (git(num.mantissa, k) \ 100000))
    ElseIf j = 4 Then
        Call set(ip.mantissa, k, 10000 * (git(num.mantissa, k) \ 10000))
    ElseIf j = 5 Then
        Call set(ip.mantissa, k, 1000 * (git(num.mantissa, k) \ 1000))
    ElseIf j = 6 Then
        Call set(ip.mantissa, k, 100 * (git(num.mantissa, k) \ 100))
    ElseIf j = 7 Then
        Call set(ip.mantissa, k, 10 * (git(num.mantissa, k) \ 10))
    ElseIf j = 8 Then
        Call set(ip.mantissa, k, git(num.mantissa, k))
    End If
    ip.exponent = ex + BIAS
    ip.sign = num.sign
    result = ip
End Sub

Function fpfix_is_odd& (num As decfloat)
    Dim As Long ex, j, k

    ex = (num.exponent And &H7FFFFFFF) - BIAS
    If ex < 1 Then
        fpfix_is_odd = 0: Exit Function
    End If
    If ex >= (NUM_DIGITS) Then
        Print "error in function fpfix_is_odd"
        fpfix_is_odd = 99999999: Exit Function
    End If
    k = ex \ 8
    j = ex Mod 8

    If j = 1 Then
        fpfix_is_odd = (git(num.mantissa, k) \ 10000000) And 1: Exit Function
    ElseIf j = 2 Then
        fpfix_is_odd = (git(num.mantissa, k) \ 1000000) And 1: Exit Function
    ElseIf j = 3 Then
        fpfix_is_odd = (git(num.mantissa, k) \ 100000) And 1: Exit Function
    ElseIf j = 4 Then
        fpfix_is_odd = (git(num.mantissa, k) \ 10000) And 1: Exit Function
    ElseIf j = 5 Then
        fpfix_is_odd = (git(num.mantissa, k) \ 1000) And 1: Exit Function
    ElseIf j = 6 Then
        fpfix_is_odd = (git(num.mantissa, k) \ 100) And 1: Exit Function
    ElseIf j = 7 Then
        fpfix_is_odd = (git(num.mantissa, k) \ 10) And 1: Exit Function
    ElseIf j = 8 Then
        fpfix_is_odd = git(num.mantissa, k) And 1: Exit Function
    End If
    fpfix_is_odd = 0
End Function

Function fp2dbl# (n As decfloat)
    Dim As Long ex
    Dim As String v, f, ts
    If n.exponent > 0 Then
        ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
    Else
        ex = 0
    End If
    If n.sign Then v = "-" Else v = " "
    ts = Trim$(Str$(git(n.mantissa, 0)))
    If Len(ts) < 8 Then
        ts = ts + String$(8 - Len(ts), "0")
    End If
    v = v + Left$(ts, 1) + "." + Mid$(ts, 2)
    ts = Trim$(Str$(git(n.mantissa, 1)))
    If Len(ts) < 8 Then
        ts = String$(8 - Len(ts), "0") + ts
    End If
    v = v + ts

    f = Str$(Abs(ex))
    f = String$(5 - Len(f), "0") + f
    If ex < 0 Then v = v + "E-" Else v = v + "E+"
    v = v + f
    fp2dbl# = Val(v)
End Function

Function fp2str_fix$ (n As decfloat, places As Long)
    Dim As Long i, ex
    Dim As String v, ts, s
    If n.exponent > 0 Then
        ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
    Else
        ex = 0
    End If
    If n.sign Then s = "-" Else s = " "
    ts = Trim$(Str$(git(n.mantissa, 0)))
    If Len(ts) < 8 Then
        ts = ts + String$(8 - Len(ts), "0")
    End If
    v = ts
    For i = 1 To NUM_DWORDS - 1
        ts = Trim$(Str$(git(n.mantissa, i)))
        If Len(ts) < 8 Then
            ts = String$(8 - Len(ts), "0") + ts
        End If
        v = v + ts
    Next
    If places < NUM_DIGITS Then
        v = Left$(v, places)
    End If
    If ex = 0 Then
        v = Left$(v, 1) + "." + Mid$(v, 2)
    ElseIf ex < 0 Then
        v = "0." + String$(Abs(ex) - 1, "0") + v
    ElseIf ex > 0 Then
        v = Left$(v, ex + 1) + "." + Mid$(v, ex + 2)
    End If
    fp2str_fix$ = s + v
End Function

Function fp2str$ (n As decfloat, places As Long)
    Dim As Long ex
    If n.exponent > 0 Then
        ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
    Else
        ex = 0
    End If
    If Abs(ex) < places Then
        fp2str = fp2str_fix(n, places)
    Else
        fp2str = fp2str_exp(n, places)
    End If
End Function

Sub str2fp (result As decfloat, value As String)
    Dim As Long j, s, d, e, ep, ex, es, i, f, fp, fln
    Dim As String c, f1, f2, f3, ts
    Dim As Unsigned Long ulng
    Dim n As decfloat
    j = 1
    s = 1
    d = 0
    e = 0
    ep = 0
    ex = 0
    es = 1
    i = 0
    f = 0
    fp = 0
    f1 = ""
    f2 = ""
    f3 = ""
    value = UCase$(value)
    fln = Len(value)

    While j <= fln
        c = Mid$(value, j, 1)
        If ep = 1 Then
            If c = " " Then
                j = j + 1
                GoTo skip_while
            End If
            If c = "-" Then
                es = -es
                c = ""
            End If
            If c = "+" Then
                j = j + 1
                GoTo skip_while
            End If
            If (c = "0") And (f3 = "") Then
                j = j + 1
                GoTo skip_while
            End If
            If (c > "/") And (c < ":") Then 'c is digit between 0 and 9
                f3 = f3 + c
                ex = 10 * ex + (Asc(c) - 48)
                j = j + 1
                GoTo skip_while
            End If
        End If

        If c = " " Then
            j = j + 1
            GoTo skip_while
        End If
        If c = "-" Then
            s = -s
            j = j + 1
            GoTo skip_while
        End If
        If c = "+" Then
            j = j + 1
            GoTo skip_while
        End If
        If c = "." Then
            If d = 1 Then
                j = j + 1
                GoTo skip_while
            End If
            d = 1
        End If
        If (c > "/") And (c < ":") Then 'c is digit between 0 and 9
            If ((c = "0") And (i = 0)) Then
                If d = 0 Then
                    j = j + 1
                    GoTo skip_while
                End If
                If (d = 1) And (f = 0) Then
                    e = e - 1
                    j = j + 1
                    GoTo skip_while
                End If
            End If
            If d = 0 Then
                f1 = f1 + c
                i = i + 1
            Else
                If (c > "0") Then
                    fp = 1
                End If
                f2 = f2 + c
                f = f + 1
            End If
        End If
        If c = "E" Or c = "D" Then
            ep = 1
        End If
        j = j + 1
        skip_while:
    Wend
    If fp = 0 Then
        f = 0
        f2 = ""
    End If

    If s = -1 Then s = &H8000 Else s = 0
    n.sign = s
    ex = es * ex - 1 + i + e
    f1 = f1 + f2
    f1 = Mid$(f1, 1, 1) + Right$(f1, Len(f1) - 1)
    fln = Len(f1)
    If Len(f1) > (NUM_DIGITS + 1 + 8) Then
        f1 = Mid$(f1, 1, (NUM_DIGITS + 1 + 8))
    End If
    While Len(f1) < (NUM_DIGITS + 1 + 8)
        f1 = f1 + "0"
    Wend
    j = 1
    For i = 0 To NUM_DWORDS
        ts = Mid$(f1, j, 8)
        ulng = Val(ts)
        Call set(n.mantissa, i, ulng)
        If ulng <> 0 Then fp = 1
        j = j + 8
    Next
    If fp Then n.exponent = (ex + BIAS + 1) Else n.exponent = 0
    result = n
End Sub

Sub si2fp (result As decfloat, m As Integer64, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat fac1
    Dim As Long i
    Dim As Integer64 n
    n = Abs(m)

    If n > 9999999999999999 Then
        Call str2fp(fac1, Str$(m))
        result = fac1: Exit Sub
    End If

    For i = 1 To digits
        Call set(fac1.mantissa, i, 0)
    Next

    If m = 0 Then
        fac1.exponent = 0
        fac1.sign = 0
        result = fac1: Exit Sub
    End If

    fac1.exponent = BIAS
    If n < 100000000 Then
        If n < 10 Then
            Call set(fac1.mantissa, 0, n * 10000000)
            fac1.exponent = fac1.exponent + 1
        ElseIf n < 100 Then
            Call set(fac1.mantissa, 0, n * 1000000)
            fac1.exponent = fac1.exponent + 2
        ElseIf n < 1000 Then
            Call set(fac1.mantissa, 0, n * 100000)
            fac1.exponent = fac1.exponent + 3
        ElseIf n < 10000 Then
            Call set(fac1.mantissa, 0, n * 10000)
            fac1.exponent = fac1.exponent + 4
        ElseIf n < 100000 Then
            Call set(fac1.mantissa, 0, n * 1000)
            fac1.exponent = fac1.exponent + 5
        ElseIf n < 1000000 Then
            Call set(fac1.mantissa, 0, n * 100)
            fac1.exponent = fac1.exponent + 6
        ElseIf n < 10000000 Then
            Call set(fac1.mantissa, 0, n * 10)
            fac1.exponent = fac1.exponent + 7
        ElseIf n < 100000000 Then
            Call set(fac1.mantissa, 0, n)
            fac1.exponent = fac1.exponent + 8
        End If
    End If
    If n > 99999999 Then
        fac1.exponent = fac1.exponent + 8
        If n < 1000000000 Then
            Call set(fac1.mantissa, 0, n \ 10)
            Call set(fac1.mantissa, 1, (n Mod 10) * 10000000)
            fac1.exponent = fac1.exponent + 1
        ElseIf n < 100000000000 Then
            Call set(fac1.mantissa, 0, n \ 100)
            Call set(fac1.mantissa, 1, (n Mod 100) * 1000000)
            fac1.exponent = fac1.exponent + 2
        ElseIf n < 1000000000000 Then
            Call set(fac1.mantissa, 0, n \ 1000)
            Call set(fac1.mantissa, 1, (n Mod 1000) * 100000)
            fac1.exponent = fac1.exponent + 3
        ElseIf n < 10000000000000 Then
            Call set(fac1.mantissa, 0, n \ 10000)
            Call set(fac1.mantissa, 1, (n Mod 10000) * 10000)
            fac1.exponent = fac1.exponent + 4
        ElseIf n < 100000000000000 Then
            Call set(fac1.mantissa, 0, n \ 100000)
            Call set(fac1.mantissa, 1, (n Mod 100000) * 1000)
            fac1.exponent = fac1.exponent + 5
        ElseIf n < 1000000000000000 Then
            Call set(fac1.mantissa, 0, n \ 1000000)
            Call set(fac1.mantissa, 1, (n Mod 1000000) * 100)
            fac1.exponent = fac1.exponent + 6
        ElseIf n < 10000000000000000 Then
            Call set(fac1.mantissa, 0, n \ 10000000)
            Call set(fac1.mantissa, 1, (n Mod 10000000) * 10)
            fac1.exponent = fac1.exponent + 7
        ElseIf n < 100000000000000000 Then
            Call set(fac1.mantissa, 0, n \ 100000000)
            Call set(fac1.mantissa, 1, n Mod 100000000)
            fac1.exponent = fac1.exponent + 8
        End If
    End If
    If m < 0 Then
        fac1.sign = &H8000
    Else
        fac1.sign = 0
    End If
    result = fac1
End Sub

Sub RSHIFT_1 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = digits To 1 Step -1
        v1 = git(mantissa.mantissa, i) \ 10
        v2 = git(mantissa.mantissa, i - 1) Mod 10
        v2 = v2 * 10000000 + v1
        Call set(mantissa.mantissa, i, v2)
    Next
    Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 10)
End Sub

Sub LSHIFT_1 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = 0 To digits - 1
        v1 = git(mantissa.mantissa, i) Mod 10000000
        v2 = git(mantissa.mantissa, i + 1) \ 10000000
        Call set(mantissa.mantissa, i, v1 * 10 + v2)
        Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 10000000)
    Next
    Call set(mantissa.mantissa, digits, 10 * (git(mantissa.mantissa, digits) Mod 10000000))
End Sub

Sub RSHIFT_2 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = digits To 1 Step -1
        v1 = git(mantissa.mantissa, i) \ 100
        v2 = git(mantissa.mantissa, i - 1) Mod 100
        v2 = v2 * 1000000 + v1
        Call set(mantissa.mantissa, i, v2)
    Next
    Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 100)
End Sub

Sub LSHIFT_2 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = 0 To digits - 1
        v1 = git(mantissa.mantissa, i) Mod 1000000
        v2 = git(mantissa.mantissa, i + 1) \ 1000000
        Call set(mantissa.mantissa, i, v1 * 100 + v2)
        Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 1000000)
    Next
    Call set(mantissa.mantissa, digits, 100 * (git(mantissa.mantissa, digits) Mod 1000000))
End Sub

Sub RSHIFT_3 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = digits To 1 Step -1
        v1 = git(mantissa.mantissa, i) \ 1000
        v2 = git(mantissa.mantissa, i - 1) Mod 1000
        v2 = v2 * 100000 + v1
        Call set(mantissa.mantissa, i, v2)
    Next
    Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 1000)
End Sub

Sub LSHIFT_3 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = 0 To digits - 1
        v1 = git(mantissa.mantissa, i) Mod 100000
        v2 = git(mantissa.mantissa, i + 1) \ 100000
        Call set(mantissa.mantissa, i, v1 * 1000 + v2)
        Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 100000)
    Next
    Call set(mantissa.mantissa, digits, 1000 * (git(mantissa.mantissa, digits) Mod 100000))
End Sub

Sub RSHIFT_4 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = digits To 1 Step -1
        v1 = git(mantissa.mantissa, i) \ 10000
        v2 = git(mantissa.mantissa, i - 1) Mod 10000
        v2 = v2 * 10000 + v1
        Call set(mantissa.mantissa, i, v2)
    Next
    Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 10000)
End Sub

Sub LSHIFT_4 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = 0 To digits - 1
        v1 = git(mantissa.mantissa, i) Mod 10000
        v2 = git(mantissa.mantissa, i + 1) \ 10000
        Call set(mantissa.mantissa, i, v1 * 10000 + v2)
        Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 10000)
    Next
    Call set(mantissa.mantissa, digits, 10000 * (git(mantissa.mantissa, digits) Mod 10000))
End Sub

Sub RSHIFT_5 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = digits To 1 Step -1
        v1 = git(mantissa.mantissa, i) \ 100000
        v2 = git(mantissa.mantissa, i - 1) Mod 100000
        v2 = v2 * 1000 + v1
        Call set(mantissa.mantissa, i, v2)
    Next
    Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 100000)
End Sub

Sub LSHIFT_5 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = 0 To digits - 1
        v1 = git(mantissa.mantissa, i) Mod 1000
        v2 = git(mantissa.mantissa, i + 1) \ 1000
        Call set(mantissa.mantissa, i, v1 * 100000 + v2)
        Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 1000)
    Next
    Call set(mantissa.mantissa, digits, 100000 * (git(mantissa.mantissa, digits) Mod 1000))
End Sub

Sub RSHIFT_6 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = digits To 1 Step -1
        v1 = git(mantissa.mantissa, i) \ 1000000
        v2 = git(mantissa.mantissa, i - 1) Mod 1000000
        v2 = v2 * 100 + v1
        Call set(mantissa.mantissa, i, v2)
    Next
    Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 1000000)
End Sub

Sub LSHIFT_6 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = 0 To digits - 1
        v1 = git(mantissa.mantissa, i) Mod 100
        v2 = git(mantissa.mantissa, i + 1) \ 100
        Call set(mantissa.mantissa, i, v1 * 1000000 + v2)
        Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 100)
    Next
    Call set(mantissa.mantissa, digits, 1000000 * (git(mantissa.mantissa, digits) Mod 100))
End Sub

Sub RSHIFT_7 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = digits To 1 Step -1
        v1 = git(mantissa.mantissa, i) \ 10000000
        v2 = git(mantissa.mantissa, i - 1) Mod 10000000
        v2 = v2 * 10 + v1
        Call set(mantissa.mantissa, i, v2)
    Next
    Call set(mantissa.mantissa, 0, git(mantissa.mantissa, 0) \ 10000000)
End Sub

Sub LSHIFT_7 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As Unsigned Long v1, v2
    Dim As Long i
    For i = 0 To digits - 1
        v1 = git(mantissa.mantissa, i) Mod 10
        v2 = git(mantissa.mantissa, i + 1) \ 10
        Call set(mantissa.mantissa, i, v1 * 10000000 + v2)
        Call set(mantissa.mantissa, i + 1, git(mantissa.mantissa, i + 1) Mod 10)
    Next
    Call set(mantissa.mantissa, digits, 10000000 * (git(mantissa.mantissa, digits) Mod 10))
End Sub

Sub RSHIFT_8 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As Long i
    For i = digits To 1 Step -1
        Call set(mantissa.mantissa, i, git(mantissa.mantissa, i - 1))
    Next
    Call set(mantissa.mantissa, 0, 0)
End Sub

Sub LSHIFT_8 (mantissa As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As Long i
    For i = 0 To digits - 1
        Call set(mantissa.mantissa, i, git(mantissa.mantissa, i + 1))
    Next
    Call set(mantissa.mantissa, digits, 0)
End Sub

Function fpcmp& (x As decfloat, y As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As Long c, i
    If x.sign < y.sign Then fpcmp = -1: Exit Function
    If x.sign > y.sign Then fpcmp = 1: Exit Function
    If x.sign = y.sign Then
        If x.exponent = y.exponent Then
            For i = 0 To digits
                c = git(x.mantissa, i) - git(y.mantissa, i)
                If c <> 0 Then Exit For
            Next
            If c < 0 Then fpcmp = -1: Exit Function
            If c = 0 Then fpcmp = 0: Exit Function
            If c > 0 Then fpcmp = 1: Exit Function
        End If
        If x.exponent < y.exponent Then fpcmp = -1: Exit Function
        If x.exponent > y.exponent Then fpcmp = 1: Exit Function
    End If
    ' if we reach this point it means that the signs are different
    ' and if the sign of x is set meaning that x is negative then x < y

End Function

Sub NORM_FAC1 (fac1 As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    ' normalize the number in fac1
    ' all routines exit through this one.

    'see if the mantissa is all zeros.
    'if so, set the exponent and sign equal to 0.
    Dim As Long i, er, f
    er = 0: f = 0
    For i = 0 To digits
        If git(fac1.mantissa, i) > 0 Then f = 1
    Next
    If f = 0 Then
        fac1.exponent = 0
        fac1.sign = 0
        Exit Sub
        'if the highmost Digit in fac1_man is nonzero,
        'shift the mantissa right 1 Digit and
        'increment the exponent
    ElseIf git(fac1.mantissa, 0) > 99999999 Then
        Call RSHIFT_1(fac1, digits)
        fac1.exponent = fac1.exponent + 1
    Else
        'now shift fac1_man 1 to the left until a
        'nonzero digit appears in the next-to-highest
        'Digit of fac1_man.  decrement exponent for
        'each shift.
        While git(fac1.mantissa, 0) = 0
            Call LSHIFT_8(fac1, digits)
            fac1.exponent = fac1.exponent - 8
            If fac1.exponent = 0 Then
                Print "NORM_FAC1=EXPU_ERR"
                Exit Sub
            End If
        Wend
        If git(fac1.mantissa, 0) < 10 Then
            Call LSHIFT_7(fac1, digits)
            fac1.exponent = fac1.exponent - 7
        ElseIf git(fac1.mantissa, 0) < 100 Then
            Call LSHIFT_6(fac1, digits)
            fac1.exponent = fac1.exponent - 6
        ElseIf git(fac1.mantissa, 0) < 1000 Then
            Call LSHIFT_5(fac1, digits)
            fac1.exponent = fac1.exponent - 5
        ElseIf git(fac1.mantissa, 0) < 10000 Then
            Call LSHIFT_4(fac1, digits)
            fac1.exponent = fac1.exponent - 4
        ElseIf git(fac1.mantissa, 0) < 100000 Then
            Call LSHIFT_3(fac1, digits)
            fac1.exponent = fac1.exponent - 3
        ElseIf git(fac1.mantissa, 0) < 1000000 Then
            Call LSHIFT_2(fac1, digits)
            fac1.exponent = fac1.exponent - 2
        ElseIf git(fac1.mantissa, 0) < 10000000 Then
            Call LSHIFT_1(fac1, digits)
            fac1.exponent = fac1.exponent - 1
        End If
    End If
    'check for overflow/underflow
    If fac1.exponent < 0 Then
        Print "NORM_FAC1=EXPO_ERR"
    End If
End Sub

Sub fpadd_aux (fac1 As decfloat, fac2 As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As Unsigned Long v, c, i
    c = 0
    For i = digits To 1 Step -1
        v = git(fac2.mantissa, i) + git(fac1.mantissa, i) + c
        If v > 99999999 Then
            v = v - 100000000
            c = 1
        Else
            c = 0
        End If
        Call set(fac1.mantissa, i, v)
    Next
    v = git(fac1.mantissa, 0) + git(fac2.mantissa, 0) + c
    Call set(fac1.mantissa, 0, v)

    Call NORM_FAC1(fac1, digits)

End Sub

Sub fpsub_aux (fac1 As decfloat, fac2 As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As Long v, c, i
    c = 0
    For i = digits To 1 Step -1
        v = git(fac1.mantissa, i) - git(fac2.mantissa, i) - c
        If v < 0 Then
            v = v + 100000000
            c = 1
        Else
            c = 0
        End If
        Call set(fac1.mantissa, i, v)
    Next
    v = git(fac1.mantissa, 0) - git(fac2.mantissa, 0) - c
    Call set(fac1.mantissa, 0, v)

    Call NORM_FAC1(fac1, digits)
End Sub

Sub fpadd (result As decfloat, x As decfloat, y As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    Dim As decfloat fac1, fac2
    Dim As Long i, t, c, xsign, ysign

    xsign = x.sign: x.sign = 0
    ysign = y.sign: y.sign = 0
    c = fpcmp(x, y, digits)

    x.sign = xsign
    y.sign = ysign
    If c < 0 Then
        fac1 = y
        fac2 = x
    Else
        fac1 = x
        fac2 = y
    End If
    t = fac1.exponent - fac2.exponent
    t = ((fac1.exponent And &H7FFFFFFF) - BIAS - 1) - ((fac2.exponent And &H7FFFFFFF) - BIAS - 1)

    If t < (NUM_DIGITS + 8) Then
        'The difference between the two
        'exponents indicate how many times
        'we have to multiply the mantissa
        'of FAC2 by 10 (i.e., shift it right 1 place).
        'If we have to shift more times than
        'we have digits, the result is already in FAC1.
        t = fac1.exponent - fac2.exponent
        If t > 0 And t < (NUM_DIGITS + 8) Then 'shift

            i = t \ 8
            While i > 0
                Call RSHIFT_8(fac2, digits)
                t = t - 8
                i = i - 1
            Wend
            If t = 7 Then
                Call RSHIFT_7(fac2, digits)
            ElseIf t = 6 Then
                Call RSHIFT_6(fac2, digits)
            ElseIf t = 5 Then
                Call RSHIFT_5(fac2, digits)
            ElseIf t = 4 Then
                Call RSHIFT_4(fac2, digits)
            ElseIf t = 3 Then
                Call RSHIFT_3(fac2, digits)
            ElseIf t = 2 Then
                Call RSHIFT_2(fac2, digits)
            ElseIf t = 1 Then
                Call RSHIFT_1(fac2, digits)
            End If
        End If
        'See if the signs of the two numbers
        'are the same.  If so, add; if not, subtract.
        If fac1.sign = fac2.sign Then 'add
            Call fpadd_aux(fac1, fac2, digits)
        Else
            Call fpsub_aux(fac1, fac2, digits)
        End If
    End If
    result = fac1
End Sub

Sub fpsub (result As decfloat, x As decfloat, y As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat fac1, fac2
    fac1 = x
    fac2 = y
    fac2.sign = fac2.sign Xor &H8000
    Call fpadd(fac1, fac1, fac2, digits)
    result = fac1
End Sub

Sub fpmul (result As decfloat, x As decfloat, y As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat fac1, fac2
    Dim As Long i, j, ex, er, den, num
    Dim As Integer64 digit, carry
    Dim As Unsigned Integer64 fac3(0 To digits)

    fac1 = x
    fac2 = y
    'check exponents.  if either is zero,
    'the result is zero
    If fac1.exponent = 0 Or fac2.exponent = 0 Then 'result is zero...clear fac1.
        fac1.sign = 0
        fac1.exponent = 0
        For i = 0 To digits
            Call set(fac1.mantissa, i, 0)
        Next
        'NORM_FAC1(fac1)
        result = fac1: Exit Sub
    Else

        If ex < 0 Then
            er = EXPO_ERR
            result = fac1: Exit Sub
        End If

        'clear fac3 mantissa
        For i = 0 To digits
            fac3(i) = 0
        Next

        den = digits
        While git(fac2.mantissa, den) = 0
            den = den - 1
        Wend
        num = digits
        While git(fac1.mantissa, num) = 0
            num = num - 1
        Wend

        If num < den Then
            Swap fac1, fac2
            'fac1=y
            'fac2=x
            Swap den, num
        End If

        For j = den To 0 Step -1
            carry = 0
            digit = git(fac2.mantissa, j)
            For i = num To 0 Step -1
                fac3(i) = fac3(i) + digit * git(fac1.mantissa, i)
            Next
            For i = num To 0 Step -1
                fac3(i) = fac3(i) + carry
                carry = fac3(i) \ 100000000
                fac3(i) = (fac3(i) Mod 100000000)
            Next

            For i = digits To 1 Step -1
                fac3(i) = fac3(i - 1)
            Next
            fac3(0) = carry
        Next

        For i = 0 To digits
            Call set(fac1.mantissa, i, fac3(i))
        Next
    End If
    'now determine exponent of result.
    'as you do...watch for overflow.
    ex = fac2.exponent - BIAS + fac1.exponent
    fac1.exponent = ex
    'determine the sign of the product
    fac1.sign = fac1.sign Xor fac2.sign
    Call NORM_FAC1(fac1, digits)
    result = fac1
End Sub

Sub fpmul_si (result As decfloat, x As decfloat, y As Integer64, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat fac1, fac2
    Dim As Long count, ex, er, i
    Dim As Integer64 carry, digit, prod, value
    fac1 = x
    digit = Abs(y)
    If digit > 99999999 Then
        Call si2fp(fac2, y, digits)
        Call fpmul(fac1, fac1, fac2, digits)
        result = fac1: Exit Sub
    End If
    'check exponents.  if either is zero,
    'the result is zero
    If fac1.exponent = 0 Or y = 0 Then 'result is zero...clear fac1.
        fac1.sign = 0
        fac1.exponent = 0
        For count = 0 To digits
            Call set(fac1.mantissa, count, 0)
        Next
        Call NORM_FAC1(fac1, digits)
        result = fac1: Exit Sub
    Else
        If digit = 1 Then
            If y < 0 Then
                fac1.sign = fac1.sign Xor &H8000
            End If
            result = fac1: Exit Sub
        End If
        'now determine exponent of result.
        'as you do...watch for overflow.

        If ex < 0 Then
            er = EXPO_ERR
            result = fac1: Exit Sub
        End If

        carry = 0

        For i = digits To 0 Step -1
            prod = digit * git(fac1.mantissa, i) + carry
            value = (prod Mod 100000000)
            Call set(fac1.mantissa, i, value)
            carry = prod \ 100000000
        Next

        If carry < 10 Then
            Call RSHIFT_1(fac1, digits)
            fac1.exponent = fac1.exponent + 1
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10000000)
        ElseIf carry < 100 Then
            Call RSHIFT_2(fac1, digits)
            fac1.exponent = fac1.exponent + 2
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 1000000)
        ElseIf carry < 1000 Then
            Call RSHIFT_3(fac1, digits)
            fac1.exponent = fac1.exponent + 3
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 100000)
        ElseIf carry < 10000 Then
            Call RSHIFT_4(fac1, digits)
            fac1.exponent = fac1.exponent + 4
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10000)
        ElseIf carry < 100000 Then
            Call RSHIFT_5(fac1, digits)
            fac1.exponent = fac1.exponent + 5
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 1000)
        ElseIf carry < 1000000 Then
            Call RSHIFT_6(fac1, digits)
            fac1.exponent = fac1.exponent + 6
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 100)
        ElseIf carry < 10000000 Then
            Call RSHIFT_7(fac1, digits)
            fac1.exponent = fac1.exponent + 7
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10)
        ElseIf carry < 100000000 Then
            Call RSHIFT_8(fac1, digits)
            fac1.exponent = fac1.exponent + 8
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry)
        End If

    End If

    Call NORM_FAC1(fac1, digits)

    If y < 0 Then
        fac1.sign = fac1.sign Xor &H8000
    End If
    result = fac1
End Sub

Sub fpmul_ll (result As decfloat, x As decfloat, y As Integer64, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat fac1, fac2
    Dim As Long count, ex, er, i
    Dim As Integer64 carry, digit, prod, value, n0, n1
    fac1 = x
    digit = Abs(y)
    If digit > 99999999 And digit < 10000000000000000 Then
        n0 = digit \ 100000000
        n1 = digit Mod 100000000
        Call fpmul_si(fac2, fac1, n1, digits)
        fac1.exponent = fac1.exponent + 8
        Call fpmul_si(fac1, fac1, n0, digits)
        Call fpadd(fac1, fac1, fac2, digits)
        If y < 0 Then fac1.sign = fac1.sign Xor &H8000
        result = fac1: Exit Sub
    End If
    If digit > 9999999999999999 Then
        Call str2fp(fac2, Str$(y))
        Call fpmul(fac1, fac1, fac2, digits)
        result = fac1: Exit Sub
    End If
    Call si2fp(fac2, y, digits)

    'check exponents.  if either is zero,
    'the result is zero
    If fac1.exponent = 0 Or y = 0 Then 'result is zero...clear fac1.
        fac1.sign = 0
        fac1.exponent = 0
        For count = 0 To digits
            Call set(fac1.mantissa, count, 0)
        Next
        Call NORM_FAC1(fac1, digits)
        result = fac1: Exit Sub
    Else
        If digit = 1 Then
            If y < 0 Then
                fac1.sign = fac1.sign Xor &H8000
            End If
            result = fac1: Exit Sub
        End If
        'now determine exponent of result.
        'as you do...watch for overflow.

        If ex < 0 Then
            er = EXPO_ERR
            result = fac1: Exit Sub
        End If

        carry = 0

        For i = digits To 0 Step -1
            prod = digit * git(fac1.mantissa, i) + carry
            value = (prod Mod 100000000)
            Call set(fac1.mantissa, i, value)
            carry = prod \ 100000000
        Next

        If carry < 10 Then
            Call RSHIFT_1(fac1, digits)
            fac1.exponent = fac1.exponent + 1
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10000000)
        ElseIf carry < 100 Then
            Call RSHIFT_2(fac1, digits)
            fac1.exponent = fac1.exponent + 2
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 1000000)
        ElseIf carry < 1000 Then
            Call RSHIFT_3(fac1, digits)
            fac1.exponent = fac1.exponent + 3
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 100000)
        ElseIf carry < 10000 Then
            Call RSHIFT_4(fac1, digits)
            fac1.exponent = fac1.exponent + 4
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10000)
        ElseIf carry < 100000 Then
            Call RSHIFT_5(fac1, digits)
            fac1.exponent = fac1.exponent + 5
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 1000)
        ElseIf carry < 1000000 Then
            Call RSHIFT_6(fac1, digits)
            fac1.exponent = fac1.exponent + 6
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 100)
        ElseIf carry < 10000000 Then
            Call RSHIFT_7(fac1, digits)
            fac1.exponent = fac1.exponent + 7
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry * 10)
        ElseIf carry < 100000000 Then
            Call RSHIFT_8(fac1, digits)
            fac1.exponent = fac1.exponent + 8
            Call set(fac1.mantissa, 0, git(fac1.mantissa, 0) + carry)
        End If

    End If

    Call NORM_FAC1(fac1, digits)

    If y < 0 Then
        fac1.sign = fac1.sign Xor &H8000
    End If
    result = fac1
End Sub

Sub fpinv (result As decfloat, m As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As Double x
    Dim As Long k, l, ex
    Dim As Long prec
    Dim As decfloat r, r2, one, n
    n = m
    l = Log((NUM_DIGITS + 8) * 0.0625) * 1.5
    Dim As String v, ts
    If n.exponent > 0 Then
        ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
    Else
        ex = 0
    End If

    If n.sign Then v = "-" Else v = " "
    ts = Str$(git(n.mantissa, 0))
    If Len(ts) < 8 Then
        ts = ts + String$(8 - Len(ts), "0")
    End If
    v = v + Left$(ts, 1) + "." + Mid$(ts, 2)
    ts = Str$(git(n.mantissa, 1))
    If Len(ts) < 8 Then
        ts = String$(8 - Len(ts), "0") + ts
    End If
    v = v + ts
    x = Val(v)
    If x = 0 Then Print "Div 0": result = r: Exit Sub
    If x = 1 And ex = 0 Then
        Call str2fp(r, "1")
        result = r: Exit Sub
    ElseIf x = 1 Then
        x = 10
        ex = ex - 1
    End If
    ex = (-1) - ex
    x = 1 / x
    Call str2fp(r, Str$(x))
    r.exponent = ex + BIAS + 1
    Call set(one.mantissa, 0, 10000000)
    one.exponent = BIAS + 1
    r2 = r
    prec = 3
    For k = 1 To l
        prec = 2 * prec - 1
        Call fpmul(r2, n, r, prec)
        Call fpsub(r2, one, r2, prec)
        Call fpmul(r2, r, r2, prec)
        Call fpadd(r, r, r2, prec)
    Next
    result = r
End Sub

Function min& (a As Long, b As Long)
    If a < b Then min& = a Else min& = b
End Function

Function RealW# (w() As Double, j As Long)
    Dim wx As Double
    wx = ((w(j - 1) * 10000 + w(j)) * 10000 + w(j + 1)) * 10000
    If UBound(w) >= (j + 2) Then wx = wx + w(j + 2)
    RealW# = wx
End Function

Sub subtract (w() As Double, q As Long, d() As Double, ka As Long, kb As Long)
    Dim As Long j
    For j = ka To kb
        w(j) = w(j) - q * d(j - ka + 2)
    Next
End Sub

Sub normalize (w() As Double, ka As Long, q As Long)
    w(ka) = w(ka) + w(ka - 1) * 10000
    w(ka - 1) = q
End Sub

Sub finalnorm (w() As Double, kb As Long)
    Dim As Long carry, j
    For j = kb To 3 Step -1
        If w(j) < 0 Then
            carry = ((-w(j) - 1) \ 10000) + 1
        Else
            If w(j) >= 10000 Then
                carry = -(w(j) \ 10000)
            Else
                carry = 0
            End If
        End If
        w(j) = w(j) + carry * 10000
        w(j - 1) = w(j - 1) - carry
    Next
End Sub

Sub fpdiv (result As decfloat, x As decfloat, y As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat fac1, fac2
    Dim As Long i, er, is_power_of_ten

    fac1 = x
    fac2 = y

    If fac2.exponent = 0 Then ' if fac2 = 0, return
        ' a divide-by-zero error and
        ' bail out.
        For i = 0 To digits
            Call set(fac1.mantissa, i, 99999999)
        Next
        fac1.exponent = 99999 + BIAS + 1
        er = DIVZ_ERR
        result = fac1
        Exit Sub
    ElseIf fac1.exponent = 0 Then 'fact1=0, just return
        er = 0
        result = fac1
        Exit Sub
    Else
        'check to see if fac2 is a power of ten
        is_power_of_ten = 0
        If git(fac2.mantissa, 0) = 10000000 Then
            is_power_of_ten = 1
            For i = 1 To digits
                If git(fac2.mantissa, i) <> 0 Then
                    is_power_of_ten = 0
                    Exit For
                End If
            Next
        End If
        'if fac2 is a power of ten then all we need to do is to adjust the sign and exponent and we are finished
        If is_power_of_ten = 1 Then
            fac1.sign = fac1.sign Xor fac2.sign
            fac1.exponent = fac1.exponent - fac2.exponent + BIAS + 1
            result = fac1
            Exit Sub
        End If

        Dim As Double result(1 To 2 * digits + 3), n(1 To 2 * digits + 3), d(1 To 2 * digits + 3)
        Const b = 10000
        Dim As Long j, last, laststep, q, t
        Dim As Long stp
        Dim As Double xd, xn, rund
        Dim As Double w(1 To UBound(n) + 4)

        For j = 0 To digits
            n(2 * j + 2) = git(fac1.mantissa, j) \ 10000
            n(2 * j + 3) = git(fac1.mantissa, j) Mod 10000
            d(2 * j + 2) = git(fac2.mantissa, j) \ 10000
            d(2 * j + 3) = git(fac2.mantissa, j) Mod 10000
        Next
        n(1) = (fac1.exponent And &H7FFFFFFF) - BIAS - 1
        d(1) = (fac2.exponent And &H7FFFFFFF) - BIAS - 1
        For j = UBound(n) To UBound(w)
            w(j) = 0
        Next
        t = UBound(n) - 1
        w(1) = n(1) - d(1) + 1
        w(2) = 0
        For j = 2 To UBound(n)
            w(j + 1) = n(j)
        Next
        xd = (d(2) * b + d(3)) * b + d(4) + d(5) / b
        laststep = t + 2
        For stp = 1 To laststep
            xn = RealW(w(), (stp + 2))
            q = Int(xn / xd)
            last = min(stp + t + 1, UBound(w))
            Call subtract(w(), q, d(), (stp + 2), last)
            Call normalize(w(), (stp + 2), q)
        Next
        Call finalnorm(w(), (laststep + 1))
        If w(2) <> 0 Then laststep = laststep - 1
        rund = w(laststep + 1) / b
        If rund >= 0.5 Then w(laststep) = w(laststep) + 1
        If w(2) = 0 Then
            For j = 1 To t + 1
                result(j) = w(j + 1)
            Next
        Else
            For j = 1 To t + 1
                result(j) = w(j)
            Next
        End If
        If w(2) = 0 Then result(1) = w(1) - 1 Else result(1) = w(1)

        For j = 0 To digits
            Call set(fac1.mantissa, j, result(2 * j + 2) * 10000 + result(2 * j + 3))
        Next
        Call NORM_FAC1(fac1, digits)
        fac1.exponent = (result(1) + BIAS)
    End If
    fac1.sign = fac1.sign Xor fac2.sign
    result = fac1
End Sub

' sqrt(num)
Sub fpsqr (result As decfloat, num As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat r, r2, tmp, n, half
    Dim As Long ex, k, l, prec
    Dim As String ts, v
    Dim As Double x
    l = Log((NUM_DIGITS + 8) * 0.0625) * 1.5
    'l=estimated number of iterations needed
    'first estimate is accurate to about 16 digits
    'l is approximatly = to log2((NUM_DIGITS+9)/16)
    'NUM_DIGITS+9 because decfloat has an extra 9 guard digits
    n = num
    Call si2fp(tmp, 0, digits)
    If fpcmp(n, tmp, digits) = 0 Then
        Call si2fp(r, 0, digits)
        result = r
        Exit Sub
    End If
    Call si2fp(tmp, 1, digits)
    If fpcmp(n, tmp, digits) = 0 Then
        Call si2fp(r, 1, digits)
        result = r
        Exit Sub
    End If
    Call si2fp(tmp, 0, digits)
    If fpcmp(n, tmp, digits) < 0 Then
        Call si2fp(r, 0, digits)
        result = r
        Exit Sub
    End If
    '=====================================================================
    'hack to bypass the limitation of double exponent range
    'in case the number is larger than what a double can handle
    'for example, if the number is 2e500
    'we separate the exponent and mantissa in this case 2
    'if the exponent is odd then multiply the mantissa by 10
    'take the square root and assign it to decfloat
    'divide the exponent in half for square root
    'in this case 1.414213562373095e250
    If n.exponent > 0 Then
        ex = (n.exponent And &H7FFFFFFF) - BIAS - 1
    Else
        ex = 0
    End If
    ts = Trim$(Str$(git(n.mantissa, 0)))
    If Len(ts) < 8 Then
        ts = ts + String$(8 - Len(ts), "0")
    End If
    v = v + Left$(ts, 1) + "." + Mid$(ts, 2)
    ts = Trim$(Str$(git(n.mantissa, 1)))
    If Len(ts) < 8 Then
        ts = String$(8 - Len(ts), "0") + ts
    End If
    v = v + ts
    x = Val(v)
    If x = 0 Then Print "Div 0": result = r: Exit Sub
    If x = 1 And ex = 0 Then
        Call si2fp(r, 1, digits)
        result = r
        Exit Sub
    End If
    If Abs(ex) And 1 Then
        x = x * 10
        ex = ex - 1
    End If
    x = Sqr(x) 'approximation
    v = Trim$(Str$(x))
    k = InStr(v, ".")
    Call str2fp(r, v)
    r.exponent = ex \ 2 + BIAS + 1
    If Len(v) > 1 And k = 0 Then r.exponent = r.exponent + 1
    For k = 1 To digits
        Call set(half.mantissa, k, 0)
    Next
    Call set(half.mantissa, 0, 50000000)
    half.exponent = BIAS
    half.sign = 0
    '=====================================================================
    'Newton-Raphson method
    prec = 3
    For k = 1 To l + 1
        prec = 2 * prec - 1
        Call fpdiv(tmp, n, r, prec)
        Call fpadd(r2, r, tmp, prec)
        Call fpmul(r, r2, half, prec)
    Next
    result = r
End Sub

Sub fpdiv_si (result As decfloat, num As decfloat, den As Long, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat fac1
    Dim As Unsigned Integer64 carry, remder
    Dim As Integer64 i, divisor
    Dim As Integer64 quotient
    remder = 0
    divisor = Abs(den)
    fac1 = num
    If divisor = 0 Then
        Print "error: divisor = 0"
        result = fac1: Exit Sub
    End If
    If divisor > 99999999 Then
        Print "error: divisor too large"
        result = fac1: Exit Sub
    End If

    For i = 0 To digits
        quotient = git(fac1.mantissa, i) + remder * 100000000
        remder = quotient Mod divisor
        Call set(fac1.mantissa, i, quotient \ divisor)
    Next
    quotient = remder * 100000000
    quotient = quotient \ divisor
    carry = git(fac1.mantissa, 0)

    If carry = 0 Then
        Call LSHIFT_8(fac1, digits)
        fac1.exponent = fac1.exponent - 8
        Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient)
    ElseIf carry < 10 Then
        Call LSHIFT_7(fac1, digits)
        fac1.exponent = fac1.exponent - 7
        Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 10)
    ElseIf carry < 100 Then
        Call LSHIFT_6(fac1, digits)
        fac1.exponent = fac1.exponent - 6
        Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 100)
    ElseIf carry < 1000 Then
        Call LSHIFT_5(fac1, digits)
        fac1.exponent = fac1.exponent - 5
        Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 1000)
    ElseIf carry < 10000 Then
        Call LSHIFT_4(fac1, digits)
        fac1.exponent = fac1.exponent - 4
        Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 10000)
    ElseIf carry < 100000 Then
        Call LSHIFT_3(fac1, digits)
        fac1.exponent = fac1.exponent - 3
        Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 100000)
    ElseIf carry < 1000000 Then
        Call LSHIFT_2(fac1, digits)
        fac1.exponent = fac1.exponent - 2
        Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 1000000)
    ElseIf carry < 10000000 Then
        Call LSHIFT_1(fac1, digits)
        fac1.exponent = fac1.exponent - 1
        Call set(fac1.mantissa, digits, git(fac1.mantissa, digits) + quotient \ 10000000)
    End If

    'NORM_FAC1(fac1)
    If den < 0 Then
        fac1.sign = fac1.sign Xor &H8000
    End If
    result = fac1
End Sub

'fractional part of num
Sub fpfrac (result As decfloat, num As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat n
    Call fpfix(n, num)
    Call fpsub(n, num, n, digits)
    result = n
End Sub

'returns the positive of n
Sub fpabs (result As decfloat, n As decfloat)
    Dim As decfloat x
    x = n
    x.sign = 0
    result = x
End Sub

'changes the sign of n, if n is positive then n will be negative & vice versa
Sub fpneg (result As decfloat, n As decfloat)
    Dim As decfloat x
    x = n
    x.sign = x.sign Xor &H8000
    result = x
End Sub

'returns the negative of n regardless of the sign of n
Sub fpnegative (result As decfloat, n As decfloat)
    Dim As decfloat x
    x = n
    x.sign = &H8000
    result = x
End Sub

Sub fpfmod (quotient As decfloat, f_mod As decfloat, num As decfloat, denom As decfloat, digits As Long)
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat q, fm 'make copy in case the destination and source are the same
    Call fpdiv(fm, num, denom, digits): Call fpfix(q, fm)
    Call fpsub(fm, fm, q, digits): Call fpmul(fm, fm, denom, digits)
    quotient = q
    f_mod = fm
End Sub

Sub fpeps (result As decfloat, digits As Long)
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat ep
    Call si2fp(ep, 1, digits)
    ep.exponent = (-(NUM_DIGITS) + BIAS + 1)
    result = ep
End Sub

Sub fpipow (result As decfloat, x As decfloat, e As Integer64, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    'take x to an Long power
    Dim As decfloat y
    Dim As decfloat z
    Dim As Integer64 n, c
    Dim As Long i
    c = 0
    y = x
    n = Abs(e)
    z.sign = 0
    z.exponent = (BIAS + 1)
    Call set(z.mantissa, 0, 10000000)
    For i = 1 To NUM_DWORDS
        Call set(z.mantissa, i, 0)
    Next
    While n > 0
        While (n And 1) = 0
            n = n \ 2
            Call fpmul(y, y, y, digits)
            c = c + 1
        Wend
        n = n - 1
        Call fpmul(z, y, z, digits)
        c = c + 1
    Wend
    If e < 0 Then
        Call fpinv(z, z, digits)
    End If
    result = z
End Sub

Sub fpfactorial (result As decfloat, n As Long, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    Dim As Long i
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat f
    If n < 0 Then Print "inf": result = f: Exit Sub
    If n = 0 Or n = 1 Then
        Call si2fp(f, 1, digits)
        result = f: Exit Sub
    End If
    Call si2fp(f, 2, digits)
    If n = 2 Then result = f: Exit Sub
    For i = 3 To n
        Call fpmul_si(f, f, i, digits)
    Next
    result = f
End Sub

Sub fplogTaylor (result As decfloat, x As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    'taylor series
    '====================Log Guard==================
    Dim As decfloat g, zero
    Dim As Long i
    Call fpabs(g, x)
    zero.sign = 0
    zero.exponent = 0
    For i = 0 To NUM_DWORDS
        Call set(zero.mantissa, i, 0)
    Next
    If fpcmp(g, x, digits) <> 0 Then result = zero: Exit Sub
    If fpcmp(x, zero, digits) = 0 Then result = zero: Exit Sub
    '=============================================
    Dim As Long invflag
    Dim As decfloat XX, Term, Accum, x9, tmp, tmp2
    Dim As decfloat T, B, one, Q, two

    one.sign = 0
    one.exponent = (BIAS + 1)
    Call set(one.mantissa, 0, 10000000)
    two.sign = 0
    two.exponent = (BIAS + 1)
    Call set(two.mantissa, 0, 20000000)
    For i = 1 To NUM_DWORDS
        Call set(one.mantissa, i, 0)
        Call set(two.mantissa, i, 0)
    Next
    x9 = x
    If fpcmp(x, one, digits) < 0 Then
        invflag = 1
        Call fpdiv(x9, one, x9, digits)
    End If
    Call fpsub(T, x9, one, digits)
    Call fpadd(B, x9, one, digits)
    Call fpdiv(Accum, T, B, digits)
    Call fpdiv(Q, T, B, digits)
    tmp = Q
    Call fpmul(XX, Q, Q, digits)
    Dim As Long c
    c = 1
    Do
        c = c + 2
        tmp2 = tmp
        Call fpmul(Q, Q, XX, digits)
        Call fpdiv_si(Term, Q, c, digits)
        Call fpadd(Accum, tmp, Term, digits)
        Swap tmp, Accum
    Loop Until fpcmp(tmp, tmp2, digits) = 0
    Call fpmul_si(Accum, Accum, 2, digits)
    If invflag Then
        Call fpneg(Accum, Accum)
        result = Accum: Exit Sub
    End If
    result = Accum
End Sub

Sub fplog (result As decfloat, x As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    '====================Log Guard==================
    Dim As decfloat g, one, zero
    Dim As Long i, factor
    zero.sign = 0
    zero.exponent = 0
    For i = 0 To NUM_DWORDS
        Call set(zero.mantissa, i, 0)
    Next
    Call si2fp(one, 1, digits)
    Call fpabs(g, x)
    If fpcmp(g, x, digits) <> 0 Then result = zero: Exit Sub
    If fpcmp(x, zero, digits) = 0 Then result = zero: Exit Sub
    If fpcmp(x, one, digits) = 0 Then result = zero: Exit Sub
    '=============================================
    Dim As decfloat approx, ans, logx
    approx = x
    factor = 4096
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fpsqr(approx, approx, digits)
    Call fplogTaylor(logx, approx, digits)
    Call fpmul_si(ans, logx, factor, digits)
    result = ans
End Sub

Sub fpexp (result As decfloat, x As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    'taylor series
    Dim As decfloat fac, x9, temp, accum, p, term
    Dim As Long i, c
    Call si2fp(temp, 0, digits)

    fac.sign = 0
    fac.exponent = (BIAS + 1)
    Call set(fac.mantissa, 0, 10000000)
    For i = 1 To NUM_DWORDS
        Call set(fac.mantissa, i, 0)
    Next
    If fpcmp(x, temp, digits) = 0 Then result = fac: Exit Sub
    c = 1
    Call fpdiv_si(x9, x, 8192, digits) 'fpdiv_si(x, 67108864) '
    p = x9
    Call fpadd(accum, fac, x9, digits) '1 + x

    Do
        c = c + 1
        temp = accum
        Call fpdiv_si(fac, fac, c, digits)
        Call fpmul(p, p, x9, digits)
        Call fpmul(term, p, fac, digits)
        Call fpadd(accum, temp, term, digits)
    Loop Until fpcmp(accum, temp, digits) = 0
    For i = 1 To 13
        Call fpmul(accum, accum, accum, digits)
    Next
    result = accum
End Sub

Sub fpexp_cf (result As decfloat, x As decfloat, n As Long, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS

    '                       x
    '    cf =   ------------------------------
    '                         x^2
    '           2 + -------------------------
    '                           x^2
    '              6 + ----------------------
    '                             x^2
    '                 10 + ------------------
    '                               x^2
    '                     14 + --------------
    '                                 x^2
    '                          18 + ---------
    '                                   x^2
    '                              22 + -----
    '                                   26 + ...
    '           (1 + cf)
    ' exp(x) = ----------
    '           (1 - cf)

    Dim i As Long
    Dim As decfloat s, x1, x2, tmp, tmp2
    Call fpdiv_si(x1, x, 8192, digits) ' 2^13
    Call fpmul(x2, x1, x1, digits)
    Call si2fp(s, 4 * n + 6, digits)
    For i = n To 0 Step -1
        Call si2fp(tmp, 4 * i + 2, digits)
        Call fpdiv(s, x2, s, digits)
        Call fpadd(s, s, tmp, digits)
    Next
    Call fpdiv(s, x1, s, digits)
    Call si2fp(tmp, 1, digits)
    tmp2 = tmp
    Call fpadd(tmp, tmp, s, digits)
    Call fpsub(tmp2, tmp2, s, digits)
    Call fpdiv(s, tmp, tmp2, digits)
    For i = 1 To 13 ' s^13
        Call fpmul(s, s, s, digits)
    Next
    result = s
End Sub

Sub fplog_r (result As decfloat, x As decfloat, digits_in As Long)
    Dim As Long digits
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    '====================Log Guard==================
    Dim As decfloat x2, y, tmp
    Dim As Long i
    Dim As Long ex, terms, prec, n
    Dim As Double t, t2

    tmp.sign = 0
    tmp.exponent = (BIAS + 1)
    Call set(tmp.mantissa, 0, 10000000)
    For i = 1 To NUM_DWORDS
        Call set(tmp.mantissa, i, 0)
    Next
    If fpcmp(x, tmp, digits) = 0 Then result = x2: Exit Sub
    ex = (x.exponent And &H7FFFFFFF) - BIAS - 1
    t = git(x.mantissa, 0) + git(x.mantissa, 1) / 100000000
    t = t / 10000000
    t2 = Log(t) + Log(10) * ex

    n = Log((digits + 1) * 0.5) * 1.5

    Call str2fp(x2, Str$(t2))
    prec = 3
    terms = 2
    prec = 2 * prec - 1
    Call fpexp_cf(y, x2, terms, prec)
    Call fpsub(tmp, y, x, prec)
    Call fpdiv(tmp, tmp, y, prec)
    Call fpsub(x2, x2, tmp, prec)
    If digits > 4 And digits <= 9 Then
        prec = 2 * prec - 1
        terms = 2 * terms + 1
        Call fpexp_cf(y, x2, terms, prec)
        Call fpsub(tmp, y, x, prec)
        Call fpdiv(tmp, tmp, y, prec)
        Call fpsub(x2, x2, tmp, prec)
    ElseIf digits > 9 And digits < 18 Then
        For i = 1 To 3
            prec = 2 * prec - 1
            terms = 2 * terms + 1
            Call fpexp_cf(y, x2, terms, prec)
            Call fpsub(tmp, y, x, prec)
            Call fpdiv(tmp, tmp, y, prec)
            Call fpsub(x2, x2, tmp, prec)
        Next
    ElseIf digits > 17 And digits < 34 Then
        For i = 1 To 4
            prec = 2 * prec - 1
            terms = 2 * terms + 1
            Call fpexp_cf(y, x2, terms, prec)
            Call fpsub(tmp, y, x, prec)
            Call fpdiv(tmp, tmp, y, prec)
            Call fpsub(x2, x2, tmp, prec)
        Next
    ElseIf digits > 33 And digits < 65 Then
        For i = 1 To 5
            prec = 2 * prec - 1
            terms = 2 * terms + 1
            Call fpexp_cf(y, x2, terms, prec)
            Call fpsub(tmp, y, x, prec)
            Call fpdiv(tmp, tmp, y, prec)
            Call fpsub(x2, x2, tmp, prec)
        Next
    ElseIf digits > 64 Then
        For i = 1 To 6
            prec = 2 * prec - 1
            terms = 2 * terms + 1
            Call fpexp_cf(y, x2, terms, prec)
            Call fpsub(tmp, y, x, prec)
            Call fpdiv(tmp, tmp, y, prec)
            Call fpsub(x2, x2, tmp, prec)
        Next
    End If
    result = x2
End Sub

Sub fppow (result As decfloat, lhs As decfloat, rhs As decfloat)
    Dim As decfloat lhs2
    Call fplog(lhs2, lhs, NUM_DWORDS)
    Call fpmul(lhs2, lhs2, rhs, NUM_DWORDS)
    Call fpexp(lhs2, lhs2, NUM_DWORDS)
    result = lhs2
End Sub

Sub fpnroot (result As decfloat, x As decfloat, p_in As Long, digits_in As Long)
    Dim As Long digits, p, psign
    digits = digits_in
    If digits > NUM_DWORDS Then digits = NUM_DWORDS
    Dim As decfloat ry, tmp, tmp2
    Dim As Double t, t2
    Dim As Long i, ex, l, prec

    x.sign = 0
    psign = Sgn(p_in)
    p = Abs(p_in)
    l = Log((NUM_DIGITS + 8) * 0.0625) * 1.5 'calculate the number of iterations needed
    ex = (x.exponent And &H7FFFFFFF) - BIAS - 1 'extract the exponent
    t = git(x.mantissa, 0) + git(x.mantissa, 1) / 100000000 'get 16 digits from x.mantissa
    'for example, if x = 3.1415926535897932384626433832795028842 then the above would give
    't = 31415926.53589793 because the mantissa doesn't have a decimal point, it's an integer
    'each element of the mantissa holds 8 digits
    'in this example ex = 0
    t = t / 10000000 'now t = 3.141592653589793
    t2 = Log(t) / p '+ Log(10) * ex / p 'log(t ^ (1/p)) = log(t)/p + Log(10) * ex / p
    'in this example since ex = 0, it becomes: log(t ^ (1/p)) = log(t)/p
    t2 = Exp(t2) 't2=t ^ (1/p)
    Call str2fp(ry, Str$(t2)) 'convert the double t2 to decfloat in ry
    t = Log(10) * ex / p
    t2 = Exp(t - Fix(t))
    Call str2fp(tmp, Str$(t2)) 'convert the double t2 to decfloat in tmp
    Call fpmul(ry, ry, tmp, prec) 'ry = ry * Log(10) * ex / p
    str2fp tmp, "2.7182818284590452353602874713527"
    fpipow tmp, tmp, Fix(t), 24
    Call fpmul(ry, ry, tmp, 24)
    prec = 3 '3 * 8 = 24 digits, prec here means number of 8 digit elements

    Call fpipow(tmp, ry, p - 1, prec) 'tmp = ry ^ (p-1)
    Call fpdiv(tmp, x, tmp, prec) 'tmp = x * tmp
    Call fpmul_si(tmp2, ry, p - 1, prec) 'tmp2 = ry * (p-1)
    Call fpadd(tmp2, tmp2, tmp, prec) 'tmp2 = tmp2 + tmp
    Call fpdiv_si(ry, tmp2, p, prec) 'ry = tmp2 / p
    For i = 1 To l + 1
        prec = 2 * prec - 1
        Call fpipow(tmp, ry, p - 1, prec) 'tmp  = ry^(p-1)
        Call fpdiv(tmp, x, tmp, prec) 'tmp  = x/tmp
        Call fpmul_si(tmp2, ry, p - 1, prec) 'tmp2 = ry*(p-1)
        Call fpadd(tmp2, tmp2, tmp, prec) 'tmp2 = tmp2+tmp
        Call fpdiv_si(ry, tmp2, p, prec) 'ry   = tmp2/p
    Next
    If psign < 0 Then
        si2fp tmp, 1, digits
        fpdiv ry, tmp, ry, digits
    End If
    result = ry
End Sub

Sub pi_brent_salamin (pi_bs As decfloat, digits_in As Unsigned Long)
    Dim As Unsigned Long digits
    digits = digits_in
    If digits > NUMBER_OF_DIGITS Then digits = NUMBER_OF_DIGITS

    Dim As Long limit2
    Dim As decfloat c0, c1, c2, c05
    Dim As decfloat a, b, sum
    Dim As decfloat ak, bk, ck
    Dim As decfloat ab, asq
    Dim As decfloat pow2, tmp

    limit2 = -digits + BIAS + 1
    Call si2fp(c0, 0, NUMBER_OF_DIGITS): ak = c0: bk = c0: ab = c0: asq = c0
    Call si2fp(c1, 1, NUMBER_OF_DIGITS): a = c1: ck = c1: pow2 = c1
    Call si2fp(c2, 2, NUMBER_OF_DIGITS): b = c2
    Call str2fp(c05, ".5"): sum = c05
    Call si2fp(pi_bs, 3, NUMBER_OF_DIGITS)

    Call fpsqr(b, b, NUMBER_OF_DIGITS)
    Call fpdiv(b, c1, b, NUMBER_OF_DIGITS)
    While fpcmp(ck, c0, NUMBER_OF_DIGITS) <> 0 And ck.exponent > limit2
        Call fpadd(ak, a, b, NUMBER_OF_DIGITS)
        Call fpmul(ak, c05, ak, NUMBER_OF_DIGITS)
        Call fpmul(ab, a, b, NUMBER_OF_DIGITS)
        Call fpsqr(bk, ab, NUMBER_OF_DIGITS)
        Call fpmul(asq, ak, ak, NUMBER_OF_DIGITS)
        Call fpsub(ck, asq, ab, NUMBER_OF_DIGITS)
        Call fpmul(pow2, pow2, c2, NUMBER_OF_DIGITS)
        Call fpmul(tmp, pow2, ck, NUMBER_OF_DIGITS)
        Call fpsub(sum, sum, tmp, NUMBER_OF_DIGITS)
        a = ak: b = bk
    Wend
    Call fpdiv(tmp, asq, sum, NUMBER_OF_DIGITS)
    Call fpmul(pi_bs, c2, tmp, NUMBER_OF_DIGITS)
End Sub

Sub fpsin (result As decfloat, x As decfloat, digits_in As Unsigned Long)
    Dim As decfloat XX, Term, Accum, p, temp2, fac, x_2
    Dim As decfloat pi2, circ, Ab
    Dim As Long precision
    precision = digits_in

    x_2 = x
    pi2 = pi_dec
    Call fpmul_si(circ, pi2, 2, precision)
    Call fpabs(Ab, x)
    If fpcmp(Ab, circ, precision) > 0 Then
        '======== CENTRALIZE ==============
        'floor/ceil to centralize
        Dim As decfloat tmp, tmp2
        If precision > 20 Then
            pi2 = pi_dec
        End If
        Call fpmul_si(pi2, pi2, 2, precision) 'got 2*pi
        Call fpdiv(tmp, x_2, pi2, precision)
        tmp2 = tmp
        Call fpfix(tmp, tmp) 'int part
        Call fpsub(tmp, tmp2, tmp, precision) 'frac part
        Call fpmul(tmp, tmp, pi2, precision)
        x_2 = tmp
    End If

    Dim As Long lm, limit2, i
    Dim As decfloat factor
    lm = precision
    limit2 = Int(-0.45344993886092585968 + 0.022333002852398072433 * lm + 5.0461814408333079844E-7 * lm * lm - 4.2338453039804235772E-11 * lm * lm * lm)

    Call si2fp(factor, 5, precision)
    Call fpipow(factor, factor, limit2, precision)
    Call fpdiv(x_2, x_2, factor, precision) 'x_=x_/5^limit2
    '==================================
    Dim As Long sign(3): sign(3) = 1
    Dim As Long c: c = 1

    Accum = x_2
    Call si2fp(fac, 1, precision)
    p = x_2
    Call fpmul(XX, x_2, x_2, precision)
    Do
        c = c + 2
        temp2 = Accum
        Call fpmul_si(fac, fac, c * (c - 1), precision)
        Call fpmul(p, p, XX, precision)
        Call fpdiv(Term, p, fac, precision)
        If sign(c And 3) Then
            Call fpsub(Accum, temp2, Term, precision)
        Else
            Call fpadd(Accum, temp2, Term, precision)
        End If
    Loop Until fpcmp(Accum, temp2, precision) = 0
    'multiply the result by 5^limit2

    For i = 1 To limit2
        Call fpmul(p, Accum, Accum, precision)
        Call fpmul(temp2, Accum, p, precision)
        '*** sin(5*x) = 5 * sin(x) - 20 * sin(x)^3 + 16 * sin(x)^5
        Call fpmul_si(Accum, Accum, 5, precision)
        Call fpmul_si(Term, temp2, 20, precision)
        Call fpmul_si(XX, temp2, 16, precision)
        Call fpmul(XX, XX, p, precision)
        Call fpsub(Accum, Accum, Term, precision)
        Call fpadd(Accum, Accum, XX, precision)
    Next i
    result = Accum
End Sub

Sub fpcos (result As decfloat, z As decfloat, digits_in As Unsigned Long)
    Dim As decfloat x_2, pi2
    Dim As Long precision
    precision = digits_in
    Call fpdiv_si(pi2, pi_dec, 2, precision)
    Call fpsub(x_2, pi2, z, precision)

    Call fpsin(result, x_2, precision)
End Sub

Sub fptan (result As decfloat, z As decfloat, digits_in As Unsigned Long)
    Dim As decfloat x_2, s, c
    Dim As Long precision
    precision = digits_in
    x_2 = z
    Call fpsin(s, x_2, precision)
    x_2 = z
    Call fpcos(c, x_2, precision)
    Call fpdiv(result, s, c, precision)
End Sub

Sub fpatn (result As decfloat, x As decfloat, digits_in As Unsigned Long)
    Dim As Long precision, z
    precision = digits_in
    Dim As Long sign(3): sign(3) = 1
    Dim As Unsigned Long c: c = 1
    Dim As decfloat XX, Term, Accum, strC, x_2, mt, mt2, p
    Dim As decfloat decnum, one, decnum2, factor

    decnum2 = x
    decnum2.sign = 0
    Call si2fp(one, 1, precision)
    If fpcmp(decnum2, one, precision) = 0 Then
        Call fpdiv_si(result, pi_dec, 4, precision)
        result.sign = x.sign
        Exit Sub
    End If
    decnum2.sign = x.sign
    Dim As Long limit2: limit2 = 16
    Call si2fp(factor, ShL(2, limit2 - 1), precision)
    For z = 1 To limit2
        Call fpmul(decnum, decnum2, decnum2, precision)
        Call fpadd(decnum, decnum, one, precision)
        Call fpsqr(decnum, decnum, precision)
        Call fpadd(decnum, decnum, one, precision)
        Call fpdiv(decnum, decnum2, decnum, precision)
        decnum2 = decnum
    Next z

    mt = decnum
    x_2 = decnum
    p = decnum
    Call fpmul(XX, x_2, x_2, precision)
    Do
        c = c + 2
        mt2 = mt
        Call si2fp(strC, c, precision)
        Call fpmul(p, p, XX, precision)
        Call fpdiv(Term, p, strC, precision)
        If sign(c And 3) Then
            Call fpsub(Accum, mt, Term, precision)
        Else
            Call fpadd(Accum, mt, Term, precision)
        End If
        Swap mt, Accum
    Loop Until fpcmp(mt, mt2, precision) = 0
    Call fpmul(result, factor, mt, precision)
End Sub

Sub fpasin (result As decfloat, x As decfloat, digits_in As Unsigned Long)
    Dim As Long precision
    precision = digits_in
    Dim As Double num
    ' ARCSIN = ATN(x / SQR(-x * x + 1))
    '============= ARCSIN GUARD =========
    num = fp2dbl(x)
    If num > 1 Then Exit Sub
    If num < -1 Then Exit Sub
    '========================
    Dim As decfloat one, T, B, term1, minusone
    Call si2fp(one, 1, precision)
    Call si2fp(minusone, -1, precision)
    T = x
    Call fpmul(B, x, x, precision) 'x*x
    'for 1 and -1
    If fpcmp(B, one, precision) = 0 Then
        Dim As decfloat two, atn1
        Call si2fp(two, 2, precision)
        Call fpatn(atn1, one, precision)
        If fpcmp(x, minusone, precision) = 0 Then
            Call fpmul(two, two, atn1, precision)
            Call fpmul(result, two, minusone, precision)
            Exit Sub
        Else
            Call fpmul(result, two, atn1, precision)
            Exit Sub
        End If
    End If
    Call fpsub(B, one, B, precision) '1-x*x
    Call fpsqr(B, B, precision) 'sqr(1-x*x)
    Call fpdiv(term1, T, B, precision)
    Call fpatn(result, term1, precision)
End Sub

Sub fpacos (result As decfloat, x As decfloat, digits_in As Unsigned Long)
    Dim As Long precision
    precision = digits_in
    Dim As decfloat one, minusone, two, atn1, tail, T, B, term1, atnterm1 ',_x,temp
    Dim As Double num
    'ARCCOS = ATN(-x / SQR(-x * x + 1)) + 2 * ATN(1)
    '============= ARCCOS GUARD =========
    num = fp2dbl(x)
    If num > 1 Then Exit Sub
    If num < -1 Then Exit Sub
    '========================
    Call si2fp(one, 1, precision)
    Call si2fp(minusone, -1, precision)
    Call si2fp(two, 2, precision)
    Call fpatn(atn1, one, precision)
    Call fpmul(tail, two, atn1, precision) '2*atn(1)
    Call fpmul(T, minusone, x, precision) '-x
    Call fpmul(B, x, x, precision) 'x*x
    If fpcmp(B, one, precision) = 0 Then
        'for 1 and -1
        If fpcmp(x, minusone, precision) = 0 Then
            Dim As decfloat four
            Call si2fp(four, 4, precision)
            Call fpmul(result, four, atn1, precision)
            Exit Sub
        Else
            Call si2fp(result, 0, precision)
            Exit Sub
        End If
    End If
    Call fpsub(B, one, B, precision) '1-x*x
    Call fpsqr(B, B, precision) 'sqr(1-x*x)
    Call fpdiv(term1, T, B, precision)
    Call fpatn(atnterm1, term1, precision)
    Call fpadd(result, atnterm1, tail, precision)
End Sub

Sub initialize_fp
    Print "initializing constants: please wait"
    Call pi_brent_salamin(pi_dec, NUMBER_OF_DIGITS)
    Call si2fp(tan_half_num(0), 992, NUMBER_OF_DIGITS)
    Call str2fp(tan_half_num(1), "161388480")
    Call str2fp(tan_half_num(2), "7686610525440")
    Call str2fp(tan_half_num(3), "-167256984742848000")
    Call str2fp(tan_half_num(4), "2000393537524462080000")
    Call str2fp(tan_half_num(5), "-14467646220791919547392000")
    Call str2fp(tan_half_num(6), "66677300813465118447390720000")
    Call str2fp(tan_half_num(7), "-201117789910786072985458237440000")
    Call str2fp(tan_half_num(8), "400342706504764747636935691468800000")
    Call str2fp(tan_half_num(9), "-521967288977995909272835160309760000000")
    Call str2fp(tan_half_num(10), "435052278687602761865918494187323392000000")
    Call str2fp(tan_half_num(11), "-221463964316902607512694240578598338560000000")
    Call str2fp(tan_half_num(12), "63663507608965602906315837691661069058048000000")
    Call str2fp(tan_half_num(13), "-8994510946805140308046160658488525397688320000000")
    Call str2fp(tan_half_num(14), "470550277118574335327341015729793791741132800000000")
    Call str2fp(tan_half_num(15), "-3827142253897737927329040261268989506161213440000000")

    Call si2fp(tan_half_den(0), 491040, NUMBER_OF_DIGITS)
    Call str2fp(tan_half_den(1), "39540177600")
    Call str2fp(tan_half_den(2), "-1232419887578880")
    Call str2fp(tan_half_den(3), "19569067214913216000")
    Call str2fp(tan_half_den(4), "-180435497084706479616000")
    Call str2fp(tan_half_den(5), "1036847979156754234229760000")
    Call str2fp(tan_half_den(6), "-3857758118493338995884748800000")
    Call str2fp(tan_half_den(7), "9452536125806945430316537159680000")
    Call str2fp(tan_half_den(8), "-15257505370126034271052104685977600000")
    Call str2fp(tan_half_den(9), "15972199042726674823748755905478656000000")
    Call str2fp(tan_half_den(10), "-10480804895655884717678945541785518080000000")
    Call str2fp(tan_half_den(11), "4060172679143214471066061077274302873600000000")
    Call str2fp(tan_half_den(12), "-837419984702547545921539095790310985302016000000")
    Call str2fp(tan_half_den(13), "75810877980214754024960496978688999780515840000000")
    Call str2fp(tan_half_den(14), "-1913571126948868963664520130634494753080606720000000")
    Cls
End Sub

Print this item

  Newton had a fun way to approximate general roots...
Posted by: Pete - 09-13-2022, 02:52 AM - Forum: General Discussion - Replies (35)

Print this item

  Cool Line Input feature
Posted by: bert22306 - 09-13-2022, 02:18 AM - Forum: General Discussion - Replies (2)

Well, okay, this might also be one of those situations where I'm the only guy who didn't get the memo.

If we create a text file with multiple lines, each line ending with a <return>, and we use Line Input to read each line as one long string, the Line Input command only reads the top line in the file.

Okay, I thought, I can deal with that. I can always copy-paste the other lines to the top, to input each line.

No need!

All you have to do is go back to that Line Input statement, and it will automatically read the next line down, in the text file. How cool is that?

Code: (Select All)
Dim Shared a$
Open "..\Textfile_with_many_lines_each_ending_with_carriage_return.ini" For Input As #1
1 Line Input #1, a$
Call sub_to_do_whatever
Print
Input "More sentences (y/n)"; cont$
If cont$ = "y" Then
    Print
    GoTo 1
End If
Close
End

Sub sub_to_do_whatever
    Print a$
End Sub

I add one line at the bottom of the text file, which says "stop," to end the process. For this demo program, the subroutine only prints the line input from the text file.

Print this item

Lightbulb Announcing InForm-pe for QB64PE 3.2.0 on Linux
Posted by: Fifi - 09-13-2022, 02:14 AM - Forum: Announcements - Replies (2)

Hello all,

I've rewritten my multi tongues installation script to adapt it to QB64PE and I've created a fork of InForm v1.3 adapted to QB64PE 3.2.0 for the Linux OS platform that I've named InForm-pe.

If needed, I can provide the same installation script for the previous version QB64PE 3.1.0.

Please check my response (#4) to the post announcing "QB64 Phoenix Edition v3.2.0 released!" of DSMan195276 for more detailed explanations about the features of this new script.

You can download my script on my web site at home: http://l7d.ddns.net

Cheers.
Fifi

Print this item

  String math: Whole # powers easy, decimal powers!!!
Posted by: Pete - 09-12-2022, 08:58 PM - Forum: General Discussion - No Replies

I was considering adding powers to my growing string math routines, until I thought about how to handle decimal powers.

For instance:

256^2.25

A pseudo algorithm to handle this crap would go something like...

256^2+25/100 ' Make into a fraction.
256^2+1/4 ' Reduce by GCF.
256^9/4 ' Combine whole number as a fraction with the fraction.
(256^1/4)^9 ' Move the largest whole number outside the equation.
(4 root of 256)^9 ' Apply root calculation.
4^9 = 262,144

Anyway, not to bad, until you get into even something not a whole lot more complicated than log2 of 10 or 2^3.3219280948874

So ...

2^3+3219280948874/10000000000000 ' Make into a fraction.
2^3+1609640474437/5000000000000 ' Reduce by GCF.
2^16609640474437/5000000000000 ' Combine whole number as a fraction with the fraction.
(2^1/5000000000000)^16609640474437 ' Move the largest whole number outside the equation.
(5000000000000 root of 2)^16609640474437 ' Apply root calculation.
Well, if you can f'ing figure out what the 5 f'tillion root of 2 is, you can raise that to the power of 16609640474437 and get 10.


I mean to wipe out some digits and approximate, the 5th root of 2 is approx.1.148 and that to the power of 16.7 gets you pretty close to 10, so this should work, but now I'm wondering after doing square roots, how much more involved it would be to calculate general roots?

Pete

Print this item

  QB64 Phoenix Edition v3.2.0 Released!
Posted by: DSMan195276 - 09-12-2022, 07:11 PM - Forum: Announcements - Replies (22)

QB64 Phoenix Edition v3.2.0!
https://github.com/QB64-Phoenix-Edition/...tag/v3.2.0

Enhancements

  1. #21, #164 - The $Unstable command was added - @mkilgore
    • $Unstable allows usage of language features that are not yet finalized.
    • Features hidden behind $Unstable may have breaking change in new releases, unlike regular parts of the language which do not have breaking changes in new releases.
  2. #155, #164 - Added MIDI support to
    _SNDOPEN
    - @a740g, @mkilgore
    • MIDI support is current unstable, and hidden behind $Unstable:Midi.
    • MIDI is enabled by using the $MidiSoundFont metacommand to specify a soundfont for playing MIDI files.
    • The selected soundfont is compiled into your program, so the file does not need to be present at runtime.
  3. #162, #164 - Compiler settings can be supplied on the command line - @mkilgore
    • QB64-PE now accepts the
      -f
      flag for supplying settings accessible in the
      Compiler Settings
      menu.
    • Settings are only applied for that run of QB64-PE (they do not modify the preserved IDE settings)
    • Using
      -f
      with no flag will print all of the available options.

Bug Fixes
  • #161 - Fixed _MOUSEMOVE when window is resized - @mkilgore
  • #165 - Fixed compiling source files that have a
    '
    in their name - @mkilgore
  • #169, #171 - Fixed
    _SNDOPEN
    to return zero on failures. - @a740g
  • #170, #171 - Fixed
    PLAY "MB"
    so that it also causes
    SOUND
    commands to play in the background - @a740g

Full Changelog: https://github.com/QB64-Phoenix-Edition/...0...v3.2.0

Print this item

  Use LOOPs to avoid excessive RETURNs
Posted by: Pete - 09-12-2022, 03:28 PM - Forum: General Discussion - Replies (8)

Just another in my huge line of tech tips to share with the growing Phoenix community. If you enjoy this coding tip, please feel free to use the code by donating to my GOFORKME page.

Okay, so have you ever used a GOSUB routine that goes on forever, but under several conditions needs to be exited early? If so, maybe you just added several RETURN statements after said conditions. That can get messy in a hurry, and it might be hard to debug when you are searching RETURN and trying to figure out where those RETURNs return to. So for all you tired of being pasta coders out there, here is my 5-cent solution. (Lucy would be so proud....)

Instead of...

Code: (Select All)
GOSUB pete
END

Pete:
bigger_1 = 1 + 1
IF STEVE = funny_looking THEN RETURN
IF ROSES THEN VIOLETS = blue ELSE RETURN
' Blah... Blah... Blah...
PRINT "My GOFORKME page is going viral!"
IF youvehadenough THEN RETURN
LOCATE somewhere, better
RETURN

We could code it this way...

Code: (Select All)
GOSUB Pete
END

Pete:
DO
    bigger_1 = 1 + 1
    IF STEVE = funny_looking THEN EXIT DO
    IF ROSES THEN VIOLETS = blue ELSE EXIT DO
    ' Blah... Blah... Blah...
    PRINT "My GOFORKME page is going viral!"
    IF youvehadenough THEN EXIT DO
    LOCATE somewhere, better
    EXIT DO
LOOP
RETURN


Tune in NEXT time for my second tech tip: DO AND WHILE can be my pal, but NEXT will never hurt me.

Pete Big Grin

Print this item