'FRACTIONS.BAS LBB 23-02-2017
'==============
' returns the result of a division (a / b) as a fraction , rather then as a decimal number
' this means: < 2/3 > rather then < 0.66666... >
' both terms of a fraction are divided by the GCD (Greatest Common Divisor)
' results display: < x = a / b > as a decimal, and < x$ > as a "fraction to text"
' only 2 procedures: < SUB FRACTION a, b > , which calls < FUNCTION GCD (a, b) >
' examples, 10 couples of numbers loaded and divided by the main code
DATA 10
DATA 5, 0, 0, 0, 0, 6, 3, 6, -8, 6, 12, -8, -10, -24, 0.375, -0.500, 0.16, 0.08, -1.2, 0.8
[Main]
READ n
FOR i = 1 TO n
CLS
READ a, b
PRINT "a = "a, "b = "; b, "x = a / b"
!PRINT''
CALL FRACTION a, b
!PRINT''
INPUT "Type <ENTER / RETURN > to continue..."; enter$
NEXT i
!* QUIT
[Procedures]
SUB FRACTION a, b
' *** special cases a/0 or 0/0 or 0/b
IF (a <> 0) AND (b = 0) THEN PRINT, "division by zero, no result": EXIT SUB
IF (a = 0) AND (b = 0) THEN PRINT, "dividing zero by zero , undetermination, no result": EXIT SUB
IF (a = 0) AND (b <> 0) THEN x = 0: x$ = "0"
' *** common case, no zero's
x = a / b
IF x = INT(x) THEN x$ = STR$(x) ' if x = a/b is an integer
IF x <> INT(x) THEN ' if x = a/b has decimals
a = ABS(a): b = ABS(b) ' positive numbers only
k = GCD (a, b)
a = a/k
b = b/k
x$ = STR$(a) + "/" + STR$(b)
IF x < 0 THEN x$ = "-" + x$ ' restoring minus sign if needed
END IF
' *** display results
PRINT,, "x = "; x
PRINT
PRINT,, "x$ = "; x$
END SUB
FUNCTION GCD (M, N)
' GCD Greatest Common Divisor
' M and N receive the absolute values of 'a' and 'b', but also decimals
IF M = 0 OR N = 0 THEN EXIT FUNCTION
! IF M < N THEN SWAP M, N
' case decimals, make them integer and hope everything works
' N is the lower of N, M
factor = 1
WHILE N < 1
M = M*10
N = N*10
factor = factor * 10
WEND
' now classical Euclides' algorithm
DO
R = M MOD N
IF R = 0 THEN EXIT DO
M = N
N = R
END IF
LOOP
IF N < 1 THEN N = 1 ' who knows what could happen else ...
GCD = N / factor ' if no decimals, factor = 1
END FUNCTION
'FRACTIONS.BAS LBB 04-03-2017
'==============
' returns the result of a division (a / b) as a fraction , rather then as a decimal number
' this means: < 2/3 > rather then < 0.66666... >
' both terms of a fraction are divided by the GCD (Greatest Common Divisor)
' results display: < x = a / b > as a decimal, and < x$ > as a "fraction to text"
' only 2 procedures: < SUB FRACTION a, b > , which calls < FUNCTION GCD (a, b) >
' xf$ is a fractionnary number like '1 1/4'
' examples, 11 couples of numbers loaded and divided by the main code
DATA 11
DATA 5, 0, 0, 0, 0, 6, 3, 6, -8, 6, 12, -8, -10, -24, 0.375, -0.500, 0.16, 0.08, -1.2, 0.8, 5, 4
[Main]
READ n
FOR i = 1 TO n
CLS
READ a, b
PRINT "a = "a, "b = "; b, "x = a / b"
!PRINT''
CALL FRACTION a, b
!PRINT''
INPUT "Type <ENTER / RETURN > to continue..."; enter$
NEXT i
!* QUIT
[Procedures]
SUB FRACTION a, b
' *** special cases a/0 or 0/0 or 0/b
IF (a <> 0) AND (b = 0) THEN PRINT, "division by zero, no result": EXIT SUB
IF (a = 0) AND (b = 0) THEN PRINT, "dividing zero by zero , undetermination, no result": EXIT SUB
IF (a = 0) AND (b <> 0) THEN x = 0: x$ = "0"
' *** common case, no zero's
x = a / b
IF x = INT(x) THEN x$ = STR$(x) ' if x = a/b is an integer
IF x <> INT(x) THEN ' if x = a/b has decimals
a = ABS(a): b = ABS(b) ' positive numbers only
k = GCD (a, b)
a = a/k
b = b/k
x$ = STR$(a) + "/" + STR$(b)
IF x < 0 THEN x$ = "-" + x$ ' restoring minus sign if needed
'added here for displaying a fractionnal result
xf$ = ""
IF a > b THEN
a = a - b
k = GCD (a, b)
a = a/k
b = b/k
xf$ = STR$(INT(x)) + " " + STR$(a) + "/" + STR$(b)
END IF
END IF
' *** display results
PRINT,, "x = "; x
PRINT
PRINT,, "x$ = "; x$
PRINT
IF xf$ <> "" THEN PRINT,, "xf$ = "; xf$
END SUB
FUNCTION GCD (M, N)
' GCD Greatest Common Divisor
' M and N receive the absolute values of 'a' and 'b', even if decimals
IF M = 0 OR N = 0 THEN EXIT FUNCTION
! IF M < N THEN SWAP M, N
' case decimals, make them integer and hope everything works
' N is the lower of N, M
factor = 1
WHILE N < 1
M = M*10
N = N*10
factor = factor * 10
WEND
' now classical Euclides' algorithm
DO
R = M MOD N
IF R = 0 THEN EXIT DO
M = N
N = R
LOOP
IF N < 1 THEN N = 1
GCD = N / factor ' if no decimals, factor = 1
END FUNCTION