LB Booster
« FRACTIONS »

Welcome Guest. Please Login or Register.
Apr 1st, 2018, 04:19am



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
We apologize Conforums does not have any export functions to migrate data.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

Thank you Conforums members.
Speed up Liberty BASIC programs by up to ten times!
Compile Liberty BASIC programs to compact, standalone executables!
Overcome many of Liberty BASIC's bugs and limitations!
LB Booster Resources
LB Booster documentation
LB Booster Home Page
LB Booster technical Wiki
Just BASIC forum
BBC BASIC Home Page
Liberty BASIC forum (the original)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: FRACTIONS  (Read 436 times)
Optimax
New Member
Image


member is offline

Avatar




PM


Posts: 11
xx 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
 
User IP Logged

Jack Kelly
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 106
xx 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
User IP Logged

Optimax
New Member
Image


member is offline

Avatar




PM


Posts: 11
xx 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 » User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx 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.
User IP Logged

tsh73
Full Member
ImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 210
xx 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.)
User IP Logged

Optimax
New Member
Image


member is offline

Avatar




PM


Posts: 11
xx 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 » User IP Logged

SarmedNafi
Junior Member
ImageImage


member is offline

Avatar




PM


Posts: 93
xx 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...


User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx 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.
User IP Logged

SarmedNafi
Junior Member
ImageImage


member is offline

Avatar




PM


Posts: 93
xx 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 » User IP Logged

Optimax
New Member
Image


member is offline

Avatar




PM


Posts: 11
xx 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
 






User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls