Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Don't make me REPETEND myself...
#2
I did this years ago, I wonder if I could dig it up. In fact I did this with base 2 numbers! Because drawing the bar codes made some fabulous designs.

Ah I did find it in no time! Search divide and there under math/division is, n divided by d:
Code: (Select All)
_Title "n slash d to R notation and back again" '2019-04-24
' from:"Decimal Expansion of Division without Dividing  by bplus 2017-12-03"
' dove tailing Adrians and my recent dividing programs

' 2019-04-24
' I want to isolate the repeated section immediately not write the fraction out and then repeat the repeated section
' not 1/6 = .16R6 >>> but .1R6

'hmm... look like have to cycle through twice to get the length of the repeat section
' but before returning backup to start of repeat section insert the R where it starts the first time
' and end it where " repeat " starts.

'2019-04-24
' just for kicks, convert the R notation back to fraction if possible.
' Had to revert back to the redundant " repeat " form of R notation.

'2019-04-27 Thanks to Jack002's comments and replies this code to calculate adj&& may have been improved.

Randomize Timer
DefLng A-Z
Do
    Print: Print "Enter 2 integers < 3200, numerator / denominator, 0's quit, don't forget / "
    Input nd$
    slash = InStr(nd$, "/")
    If slash Then
        dvsr = Val(Mid$(nd$, slash + 1))
        If dvsr = 0 Then Print "Divisor is 0, bye.": End
        numerator = Val(Mid$(nd$, 1, slash - 1))
        If numerator = 0 Then Print "Numerator is 0, bye.": End
    Else
        Print "No slash found, bye.": End
    End If
    Cls
    d$ = divide$(numerator, dvsr)
    Print numerator; " / "; dvsr; " = "; d$

    'and now arttemp"t to convert back to fraction
    Print: Print "Check if can convert back to fraction:"
    result$ = convertRnotation2Fraction$(d$)
    If result$ <> "" Then Print result$
Loop

Function convertRnotation2Fraction$ (rNotedDecimal$)
    'check if R in the decimal
    dotPos = InStr(rNotedDecimal$, ".")
    If dotPos = 0 Then convertRnotation2Fraction$ = rNotedDecimal$: Exit Function
    RPos = InStr(rNotedDecimal$, " repeat ")
    If RPos = 0 Then convertRnotation2Fraction$ = convert2Fraction$(rNotedDecimal$): Exit Function

    'still here? we have an R and a decimal
    whole$ = Mid$(rNotedDecimal$, 1, dotPos - 1)
    If Val(whole$) = 0 Then whole$ = ""

    p = Len(rNotedDecimal$) - RPos - Len(" repeat ") + 1
    Print "Debug: repeat length ="; p
    If p > 12 Then
        Print "The length of the repeat section of: "
        Print rNotedDecimal$
        Print " is too long to convert back to fraction."
        Exit Function
    End If

    dec$ = Mid$(rNotedDecimal$, dotPos)
    Print "Debug: converting dec$ "; dec$

    'remove " repeat "
    RPos = InStr(dec$, " repeat ")
    dec1$ = Mid$(dec$, 1, RPos - 1) + Mid$(dec$, RPos + Len(" repeat "))
    dec2$ = Mid$(dec$, 1, RPos - 1)
    Print "Debug: dec1$ (double repeat), dec2$ (single repeat) = "; dec1$; ", "; dec2$

    'mult by 10^p to get the 2nd repeat part in dec1$ aligned to 1st repeat part  in dec2$
    vd1## = Val(dec1$) * 10 ^ p
    vd2## = Val(dec2$)
    n## = vd1## - vd2## 'subtract dec2$ from dec1$

    'adj&& = 1 'convert to whole numbers
    'WHILE n## <> INT(n##)
    '    adj&& = adj&& * 10
    '    n## = n## * 10
    'WEND

    'calculate adj&& from length of decimal
    ns$ = Str$(n##)
    dot = InStr(ns$, ".")
    p2 = Len(ns$) - dot
    adj&& = 10 ^ p2

    'reevaluate to avoid rounding errors from crazy floating point math
    n1&& = vd1## * adj&& - vd2## * adj&&
    Print "Debug values: vd1, vd2, adj&&, n1&& (difference * adj&& for whole number):"
    Print vd1##; ", "; vd2##; ", "; adj&&; ", "; n1&&

    d&& = (10 ^ p - 1) * adj&&
    Print "Debug: Giant numerator, denominator "; n1&&; ", "; d&& 'giant numbers

    'reduce giant numbers by Gretaest Common Divisor between them
    g&& = gcd&&(n1&&, d&&): sn&& = n1&& / g&&: sd&& = d&& / g&&

    convertRnotation2Fraction$ = whole$ + " " + _Trim$(Str$(sn&&)) + "/" + _Trim$(Str$(sd&&))
End Function

Function convert2Fraction$ (decimal$)
    dot%% = InStr(decimal$, ".")
    If dot%% > 0 Then
        whole$ = Mid$(decimal$, 1, dot%% - 1)
        If Val(whole$) = 0 Then whole$ = ""
        p%% = Len(decimal$) - dot%%
        n&& = Val(Mid$(decimal$, dot%% + 1))
        d&& = 10 ^ p%%
        g&& = gcd&&(n&&, d&&): sn&& = n&& / g&&: sd&& = d&& / g&&
        convert2Fraction$ = whole$ + " " + _Trim$(Str$(sn&&)) + "/" + _Trim$(Str$(sd&&))
    Else
        convert2Fraction$ = decimal$
    End If
End Function

Function gcd&& (a&&, b&&)
    'a and b will be changed unless make copies
    c&& = a&&: d&& = b&&
    While c&& <> 0 And d&& <> 0
        If c&& > d&& Then c&& = c&& Mod d&& Else d&& = d&& Mod c&&
    Wend
    gcd&& = c&& + d&&
End Function


Function divide$ (n, d)
    'n = original product or numerator (preserve value of n)
    'd = divisor  (also preserve value)
    c = n 'copy of n to be reduced until <= d, c will be the remainder part of division
    a = 0 'a is for answer or accumulate, the integer part of the division result

    'find lowest power of 10 such that: d * 10^p > n
    p = 0 'power of 10
    While d * (10 ^ p) < n
        p = p + 1
    Wend
    While c >= d
        If c = d Then a = a + 1: c = 0: Exit While
        p = p - 1
        If p >= 0 Then
            m = 0
            While d * m * 10 ^ p < c
                m = m + 1
            Wend
            m = m - 1
            c = c - d * m * 10 ^ p
            a = a + m * 10 ^ p
        End If
    Wend

    'Now for the decimal expansion isolating the repeating part if one
    If c <> 0 Then
        Dim b(d)
        b$ = "."
        While c <> 0

            'emergency bug out!
            loopct = loopct + 1 'loop count should not exceed 1000 for numbers I am testing
            If loopct > 1000 Then Print "Error: loop too long, bugging out! ": GoTo skip

            'track repeats  b() tracks been here once, b2() tracks been here twice
            If b(c) = 1 Then 'been here!
                If rFlag = 1 Then 'been here twice!
                    If b2(c) = 1 Then Exit While 'strike 3, we're out of here
                    b2(c) = 1
                Else
                    rFlag = 1
                    Dim b2(d)
                    b$ = b$ + " repeat "
                    b2(c) = 1
                End If
            Else
                b(c) = 1
            End If

            'c was last remainder, mult by 10 and see if some m * d > can reduce it
            tc = 10 * c
            flag = 0
            For m = 0 To 9
                If ((tc - m * d) >= 0) And ((tc - (m + 1) * d) < 0) Then
                    flag = 1: b$ = b$ + LTrim$(Str$(m))
                    Exit For
                End If
            Next
            If flag = 0 Then b$ = b$ + "0": m = 0
            c = tc - d * m
        Wend
    End If

    'OK either d divided n eventually or there is a repeated pattern recorded in b$
    skip: '< needed for debugging
    r$ = Str$(a)
    If b$ <> "" Then r$ = r$ + b$
    divide$ = r$
End Function

The repeating part is isolated and named and measured.


1/97 you are just getting started 1/269 is 268 long 1/(big prim number) always a good bet to be long.
b = b + ...
Reply


Messages In This Thread
Don't make me REPETEND myself... - by Pete - 07-31-2022, 08:57 PM
RE: Don't make me REPETEND myself... - by bplus - 07-31-2022, 11:20 PM
RE: Don't make me REPETEND myself... - by Pete - 08-01-2022, 01:00 AM
RE: Don't make me REPETEND myself... - by bplus - 08-01-2022, 03:57 PM
RE: Don't make me REPETEND myself... - by Pete - 08-01-2022, 07:10 PM
RE: Don't make me REPETEND myself... - by Jack - 08-01-2022, 07:47 PM
RE: Don't make me REPETEND myself... - by Pete - 08-03-2022, 12:30 AM
RE: Don't make me REPETEND myself... - by Jack - 08-03-2022, 01:39 AM
RE: Don't make me REPETEND myself... - by Pete - 08-03-2022, 02:49 AM
RE: Don't make me REPETEND myself... - by Stuart - 08-03-2022, 08:21 AM
RE: Don't make me REPETEND myself... - by Dav - 08-03-2022, 10:37 AM
RE: Don't make me REPETEND myself... - by Pete - 08-03-2022, 05:39 PM
RE: Don't make me REPETEND myself... - by Pete - 08-03-2022, 06:48 PM
RE: Don't make me REPETEND myself... - by Pete - 08-03-2022, 10:43 PM
RE: Don't make me REPETEND myself... - by Stuart - 08-04-2022, 07:13 AM
RE: Don't make me REPETEND myself... - by Pete - 08-04-2022, 08:37 AM
RE: Don't make me REPETEND myself... - by Jack - 08-04-2022, 09:23 AM
RE: Don't make me REPETEND myself... - by Stuart - 08-04-2022, 10:30 AM
RE: Don't make me REPETEND myself... - by bplus - 08-04-2022, 01:26 PM
RE: Don't make me REPETEND myself... - by Pete - 08-04-2022, 06:30 PM
RE: Don't make me REPETEND myself... - by Pete - 08-04-2022, 09:17 PM
RE: Don't make me REPETEND myself... - by Jack - 08-04-2022, 10:37 PM
RE: Don't make me REPETEND myself... - by Pete - 08-05-2022, 10:05 AM
RE: Don't make me REPETEND myself... - by Pete - 08-14-2022, 11:48 AM



Users browsing this thread: 3 Guest(s)