#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL decimal_val AS DOUBLE
    LOCAL target_val AS DOUBLE
    LOCAL num AS LONG
    LOCAL den AS LONG
    LOCAL prev_num AS LONG
    LOCAL prev_den AS LONG
    LOCAL temp_num AS LONG
    LOCAL temp_den AS LONG
    LOCAL int_part AS LONG
    LOCAL frac_part AS DOUBLE
    LOCAL eps AS DOUBLE
    LOCAL i AS LONG
    LOCAL a AS LONG
    LOCAL b AS LONG
    LOCAL t AS LONG
    LOCAL temp_str AS STRING

    ' Decimal to fraction converter using continued fractions
    ' Finds best rational approximation within epsilon

    PRINT "Decimal to Fraction Converter"
    PRINT "============================="
    PRINT ""

    ' Convert 0.333333 to 1/3
    decimal_val = 0.333333
    eps = 0.0001

    int_part = INT(decimal_val)
    frac_part = decimal_val - int_part

    num = 1
    den = 1
    prev_num = 0
    prev_den = 1
    temp_num = 1
    temp_den = 0

    i = 0
    WHILE i < 20
        IF frac_part < eps THEN
            i = 20
        ELSE
            temp_num = num
            temp_den = den
            num = INT(1 / frac_part) * num + prev_num
            den = INT(1 / frac_part) * den + prev_den
            prev_num = temp_num
            prev_den = temp_den
            frac_part = 1 / frac_part - INT(1 / frac_part)
            IF frac_part < 0 THEN frac_part = 0 - frac_part
            target_val = int_part + num / den
            IF ABS(decimal_val - target_val) < eps THEN
                i = 20
            END IF
        END IF
        i = i + 1
    WEND

    ' Add back integer part
    num = int_part * den + num
    ' Reduce
    a = num
    b = den
    WHILE b <> 0
        t = b
        b = a MOD b
        a = t
    WEND
    IF a > 0 THEN
        num = num / a
        den = den / a
    END IF

    temp_str = STR$(num)
    PRINT "0.333333 = " + temp_str + "/" + STR$(den)

    ' Convert 0.75 to 3/4
    decimal_val = 0.75
    eps = 0.0001
    int_part = INT(decimal_val)
    frac_part = decimal_val - int_part
    num = 1
    den = 1
    prev_num = 0
    prev_den = 1

    i = 0
    WHILE i < 20
        IF frac_part < eps THEN
            i = 20
        ELSE
            temp_num = num
            temp_den = den
            num = INT(1 / frac_part) * num + prev_num
            den = INT(1 / frac_part) * den + prev_den
            prev_num = temp_num
            prev_den = temp_den
            frac_part = 1 / frac_part - INT(1 / frac_part)
            IF frac_part < 0 THEN frac_part = 0 - frac_part
            target_val = int_part + num / den
            IF ABS(decimal_val - target_val) < eps THEN
                i = 20
            END IF
        END IF
        i = i + 1
    WEND

    num = int_part * den + num
    a = num
    b = den
    WHILE b <> 0
        t = b
        b = a MOD b
        a = t
    WEND
    IF a > 0 THEN
        num = num / a
        den = den / a
    END IF

    temp_str = STR$(num)
    PRINT "0.75 = " + temp_str + "/" + STR$(den)

    ' Convert 0.142857 to 1/7 approx
    decimal_val = 0.142857
    eps = 0.000001
    int_part = INT(decimal_val)
    frac_part = decimal_val - int_part
    num = 1
    den = 1
    prev_num = 0
    prev_den = 1

    i = 0
    WHILE i < 20
        IF frac_part < eps THEN
            i = 20
        ELSE
            temp_num = num
            temp_den = den
            num = INT(1 / frac_part) * num + prev_num
            den = INT(1 / frac_part) * den + prev_den
            prev_num = temp_num
            prev_den = temp_den
            frac_part = 1 / frac_part - INT(1 / frac_part)
            IF frac_part < 0 THEN frac_part = 0 - frac_part
            target_val = int_part + num / den
            IF ABS(decimal_val - target_val) < eps THEN
                i = 20
            END IF
        END IF
        i = i + 1
    WEND

    num = int_part * den + num
    a = num
    b = den
    WHILE b <> 0
        t = b
        b = a MOD b
        a = t
    WEND
    IF a > 0 THEN
        num = num / a
        den = den / a
    END IF

    temp_str = STR$(num)
    PRINT "0.142857 = " + temp_str + "/" + STR$(den)

    ' Convert 1.618 (golden ratio approx)
    decimal_val = 1.618
    eps = 0.001
    int_part = INT(decimal_val)
    frac_part = decimal_val - int_part
    num = 1
    den = 1
    prev_num = 0
    prev_den = 1

    i = 0
    WHILE i < 20
        IF frac_part < eps THEN
            i = 20
        ELSE
            temp_num = num
            temp_den = den
            num = INT(1 / frac_part) * num + prev_num
            den = INT(1 / frac_part) * den + prev_den
            prev_num = temp_num
            prev_den = temp_den
            frac_part = 1 / frac_part - INT(1 / frac_part)
            IF frac_part < 0 THEN frac_part = 0 - frac_part
            target_val = int_part + num / den
            IF ABS(decimal_val - target_val) < eps THEN
                i = 20
            END IF
        END IF
        i = i + 1
    WEND

    num = int_part * den + num
    a = num
    b = den
    WHILE b <> 0
        t = b
        b = a MOD b
        a = t
    WEND
    IF a > 0 THEN
        num = num / a
        den = den / a
    END IF

    temp_str = STR$(num)
    PRINT "1.618 = " + temp_str + "/" + STR$(den) + " (phi approx)"

    ' Convert 3.14159 to 355/113 (famous pi approx)
    decimal_val = 3.14159
    eps = 0.00001
    int_part = INT(decimal_val)
    frac_part = decimal_val - int_part
    num = 1
    den = 1
    prev_num = 0
    prev_den = 1

    i = 0
    WHILE i < 20
        IF frac_part < eps THEN
            i = 20
        ELSE
            temp_num = num
            temp_den = den
            num = INT(1 / frac_part) * num + prev_num
            den = INT(1 / frac_part) * den + prev_den
            prev_num = temp_num
            prev_den = temp_den
            frac_part = 1 / frac_part - INT(1 / frac_part)
            IF frac_part < 0 THEN frac_part = 0 - frac_part
            target_val = int_part + num / den
            IF ABS(decimal_val - target_val) < eps THEN
                i = 20
            END IF
        END IF
        i = i + 1
    WEND

    num = int_part * den + num
    a = num
    b = den
    WHILE b <> 0
        t = b
        b = a MOD b
        a = t
    WEND
    IF a > 0 THEN
        num = num / a
        den = den / a
    END IF

    temp_str = STR$(num)
    PRINT "3.14159 = " + temp_str + "/" + STR$(den) + " (pi approx)"

    PRINT ""
    PRINT "Fraction converter demo complete."

    FUNCTION = 0
END FUNCTION
