Division without dividing!
#1
Code:
_TITLE "Dividing 2 Integers Without Division!  by bplus 2017-12-02"
RANDOMIZE TIMER
DEFLNG A-Z
dvsr = INT(RND * 300) + 2
FOR numerator = 1 TO 1000
    IF numerator MOD 20 = 0 THEN
        INPUT "Press enter for more, any other quits "; cont$
        IF LEN(cont$) THEN END
        CLS
    END IF
    PRINT numerator; " / "; dvsr; " = "; divide$(numerator, dvsr)
NEXT

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
    divide$ = STR$(a) + " Remainder" + STR$(c)
END FUNCTION
B += x
Reply
#2
@Bplus,

This would be a really cool algorithm if it worked correctly.
Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.
profile for Walter Whitman at Stack Overflow, Q&A for professional and enthusiast programmers


Reply
#3
nice work, bplus.

here's my version...

Code:
'division of two integers by subtraction and addition to 3 decimal places
DEFLNG A-Z
COLOR 15, 0
PRINT "Division of two numbers by subtraction & addition to 3 decimal places"
PRINT "---------------------------------------------------------------------"
PRINT
INPUT "Input 1st number       "; A
INPUT "Input 2nd number       "; B
PRINT
'integer portion
A1 = A
C1 = 0
WHILE A1 >= B
    C1 = C1 + 1
    A1 = A1 - B
WEND
'1st decimal place
C2 = 0
A2 = 0
FOR i = 1 TO 10 'multiply A1 by 10
    A2 = A2 + A1
NEXT i
WHILE A2 >= B
    C2 = C2 + 1
    A2 = A2 - B
WEND
'2nd decimal place
C3 = 0
A3 = 0
FOR i = 1 TO 10 'multiply A2 by 10
    A3 = A3 + A2
NEXT i
WHILE A3 >= B
    C3 = C3 + 1
    A3 = A3 - B
WEND
'3rd decimal place
C4 = 0
A4 = 0
FOR i = 1 TO 10 'multiply A3 by 10
    A4 = A4 + A3
NEXT i
WHILE A4 >= B
    C4 = C4 + 1
    A4 = A4 - B
WEND
'print result
A$ = STR$(A): B$ = STR$(B)
C1$ = STR$(C1): C2$ = STR$(C2): C3$ = STR$(C3): C4$ = STR$(C4)
10 PRINT LTRIM$(A$); " divided by "; LTRIM$(B$); " is "; LTRIM$(C1$); "."; LTRIM$(C2$); LTRIM$(C3$); LTRIM$(C4$)
END
I like to program in BASIC
With code that is simple and slick
I learnt it in school
And it is still cool
So it is my number one pick
Reply
#4
(12-03-2017, 04:04 PM)Waltersmind Wrote: @Bplus,

This would be a really cool algorithm if it worked correctly.
I did give it a number of checks. What is an example of two integers that are not working correctly?
B += x
Reply
#5
@Bplus,

Here is a screenshot of what I am getting:



...19/134 = 0.14179104477611940298507462686567
Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.
profile for Walter Whitman at Stack Overflow, Q&A for professional and enthusiast programmers


Reply
#6
Ah, I made no claims to doing decimals but I do hope to work on that next modifying Adrian's example. If he doesn't get it done first! ;-) )

Using remainders is a proper answer for division specially in the days before calculators, 0 Remainder 19 is the same as 19/134 usually more perfect than a decimal portion answer for the division which is usually either rounded or ended because the expansion is usually infinite with repeating pattern.

Also program limited to QB64 Integers, not any Integer much beyond 32000.
B += x
Reply
#7
your wish is my command....

Code:
'division of two integers by subtraction and addition to n decimal places
DEFLNG A-Z
DIM A(10000)
DIM C(10000)
COLOR 15, 0
PRINT "Division of two numbers by subtraction & addition to n decimal places"
PRINT "---------------------------------------------------------------------"
PRINT
INPUT "Input 1st number       "; A
INPUT "Input 2nd number       "; B
INPUT "Decimal places ?       "; DP
PRINT

'integer portion
A(1) = A
C = 0
WHILE A(1) >= B
    C = C + 1
    A(1) = A(1) - B
WEND
A$ = STR$(A): B$ = STR$(B): C$ = STR$(C)
PRINT LTRIM$(A$); " divided by "; LTRIM$(B$); " is "; LTRIM$(C$); ".";

'decimal places
FOR j = 1 TO DP
    C(j) = 0
    A(j + 1) = 0
    FOR i = 1 TO 10 'multiply remainder by 10
        A(j + 1) = A(j + 1) + A(j)
    NEXT i
    WHILE A(j + 1) >= B
        C(j) = C(j) + 1
        A(j + 1) = A(j + 1) - B
    WEND
    C1$ = STR$(C(j))
    PRINT LTRIM$(C1$);
NEXT j
END


Attached Files Thumbnail(s)

I like to program in BASIC
With code that is simple and slick
I learnt it in school
And it is still cool
So it is my number one pick
Reply
#8
Adrian, Wow! That looks even better than your first post. Nice job!

You next challenge, should you decide to accept, is to isolate the repeating part to provide a perfect answer:
eg 19/134 = 0.1 Repeat 417910447761194029850746268656716
which is
0.1417910447761194029850746268656716417910447761194029850746268656716
417910447761194029850746268656716417910447761194029850746268656716
417910447761194029850746268656716417910447761194029850746268656716
417910447761194029850746268656716417910447761194029850746268656716
417910447761194029850746268656716417910447761194029850746268656716
417910447761194029850746268656716...

It was also written as 0.1(417910447761194029850746268656716) with line above (innards), actually () or [] would also serve that purpose.
1/3 = 0. Repeat 3 or 0.(3)
1/6 = 0.1 Repeat 6 or 0.1[6]

Hint: you can check JB forum to see how I did it.
B += x
Reply
#9
Hi Adrian, I apologize for my poor memory. This is the form that I got working in JB and now it appears in QB64 as well, still checking and not nearly as elegant as your last code post.

For 1/3 it would be .3 repeat 3
For 1/6 it would be .16 repeat 6
For 100/5 just 20
For 101/5 just 20.2 and here is where my QB64 version needs fixed reporting 20.19 repeat 9


Attached Files Thumbnail(s)

B += x
Reply
#10
Walter might like this better! I like the perfect precision.

Code:
_TITLE "Decimal Expansion of Division without Dividing  by bplus 2017-12-03"
' dove tailing Adrians and my recent dividing programs

RANDOMIZE TIMER
DEFLNG A-Z
WHILE 1
   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
   PRINT numerator; " / "; dvsr; " = "; divide$(numerator, dvsr)
WEND

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


Attached Files Thumbnail(s)

B += x
Reply
#11
Cool work, bplus!

Wow, you are are active on pretty much all the BASIC forums! I tried JB once and remembered liking it. easy to use, nice interface. But SmallBasic is your BASIC interpreter of choice?
I like to program in BASIC
With code that is simple and slick
I learnt it in school
And it is still cool
So it is my number one pick
Reply