Author |
Topic: FRACTIONS (Read 436 times) |
|
Optimax
New Member
member is offline
Posts: 11
|
|
FRACTIONS
« Thread started on: Feb 23rd, 2017, 10:56am » |
|
I wondered how some codes could give a result like 2/3 instead of 0.666666... So I tried to produce the same display. I've had much difficulties with decimals numbers. Hoping that everything now works ...
Code:
'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
|
|
Logged
|
|
|
|
Jack Kelly
Full Member
member is offline
Gender:
Posts: 106
|
|
Re: FRACTIONS
« Reply #1 on: Feb 24th, 2017, 07:41am » |
|
Bonjour, Optimax.
Your fractions program looks good to me. Your BASIC skills are impressive. But why do decimals give you difficulties?
Regards, Jack
|
|
Logged
|
|
|
|
Optimax
New Member
member is offline
Posts: 11
|
|
Re: FRACTIONS
« Reply #2 on: Feb 24th, 2017, 07:57am » |
|
Bien le bonjour,
Thanks for your interest in my short code. The difficulties with decimals could well be in the GCD (PGCD) algorithm, which is best suited for integers. So we make decimals as integers by mutiplying them by a multiple of 10 (the factor), and now it works better. A warning "number too big " could still overcome occur.
Regards
|
« Last Edit: Feb 24th, 2017, 08:40am by Optimax » |
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: FRACTIONS
« Reply #3 on: Feb 24th, 2017, 4:43pm » |
|
on Feb 24th, 2017, 07:41am, Jack Kelly wrote:But why do decimals give you difficulties? |
|
I expect it's the old problem of decimal values not always being precisely representable in binary floating-point format. The classic example is the value 0.1 which can obviously be represented precisely as a decimal number but not as a binary number.
The closest that LBB can get to 0.1 is this value (expressed as a decimal):
Code:0.1000000000000000000013552527156068805425093160010874271392822265625 For sure it's very close to 0.1 (19 zeros follow before you get to the next non-zero digit) but it's not precisely 0.1.
In this particular case, because of the way rounding works out, multiplying this value by 10 does result in an answer of exactly 1. But you won't always be so lucky, for example take the value 0.001. The closest internal representation to this is:
Code:0.00100000000000000000006437450399132682576919251005165278911590576171875 Multiplying this by 1000 doesn't give you the expected integer value; instead you get this:
Code:1.000000000000000000108420217248550443400745280086994171142578125 So now a loop like this doesn't do what you might hope it would:
Code: x = 0.001
WHILE x <> INT(x)
x *= 10
WEND
PRINT x Richard.
|
|
Logged
|
|
|
|
tsh73
Full Member
member is offline
Gender:
Posts: 210
|
|
Re: FRACTIONS
« Reply #4 on: Feb 24th, 2017, 7:17pm » |
|
I wonder what END IF on line 88 (in GCD function) supposed to do? (I just have other BASIC complaining so it made me wonder.)
|
|
Logged
|
|
|
|
Optimax
New Member
member is offline
Posts: 11
|
|
Re: FRACTIONS
« Reply #5 on: Feb 25th, 2017, 06:27am » |
|
That <END IF > has indeed nothing to do there. But LBB doesn't complain. It must have forgotten there from previous lines of code. Sorry for this.
|
« Last Edit: Feb 25th, 2017, 06:33am by Optimax » |
Logged
|
|
|
|
SarmedNafi
Junior Member
member is offline
Posts: 93
|
|
Re: FRACTIONS
« Reply #6 on: Feb 26th, 2017, 10:02am » |
|
I got this result ! Is it Normal ?
a = 9 b = 6 x = a / b
x = 1.5
x$ = 3/2
Type <ENTER / RETURN > to continue...
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: FRACTIONS
« Reply #7 on: Feb 26th, 2017, 10:53am » |
|
on Feb 26th, 2017, 10:02am, SarmedNafi wrote:I got this result ! Is it Normal ? |
|
It seems to be correct. You get the same result by dividing the numerator and denominator by 3.
Richard.
|
|
Logged
|
|
|
|
SarmedNafi
Junior Member
member is offline
Posts: 93
|
|
Re: FRACTIONS
« Reply #8 on: Feb 27th, 2017, 09:40am » |
|
Yes, it is correct,
I expects the result will be in the following format :
X$ = 1 1/2
KASIO Produce calculators give results such that or 1.5 format. Some times the decimal long fraction is not welcome. However the code is very interested, thanks to sender.
Regards
|
« Last Edit: Feb 27th, 2017, 09:44am by SarmedNafi » |
Logged
|
|
|
|
Optimax
New Member
member is offline
Posts: 11
|
|
Re: FRACTIONS
« Reply #9 on: Mar 4th, 2017, 6:29pm » |
|
Added a few lines today making fractionary numbers.
This result is displayed as a string and could not be directly converted by VAL nor by EVAL for further calculations.
Regards
Code:
'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
|
|
Logged
|
|
|
|
|