⍝ Rational number near real ⍵:

    ⎕PP ← (1+⎕FR=1287)⊃10 32    ⍝ decf vs binf ⎕PP

    rational 0.75               ⍝ three quarters.
3 4
    rational ÷3                 ⍝ one third.
1 3
    rational 9÷16               ⍝ pair of ..
9 16
    ∨/rational 9÷16             ⍝ .. relatively prime numbers:
1
    rational 11÷29              ⍝ pair matches rational of quotient ...
11 29
                                ⍝ ... for all relatively prime pairs:

    {⍵≡rational÷/⍵}¨ ∘.,⍨ sieve 2 to 100
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0

    numbs ← +/¨1⊂ 2 2 2⍴ +\10*-⍳8       ⍝ nested numeric array.
    numbs
┌─────────────────┬───────────────────┐
│0.1     0.111    │0.11     0.1111    │
│0.11111 0.1111111│0.111111 0.11111111│
└─────────────────┴───────────────────┘

    rational numbs                      ⍝ rational pairs
┌───────────────┬─────────────────┐
│    1     111  │    11     1111  │
│11111 1111111  │111111 11111111  │
├───────────────┼─────────────────┤
│    10     1000│    100     10000│
│100000 10000000│1000000 100000000│
└───────────────┴─────────────────┘

    numbs ≡ ÷⌿ rational numbs           ⍝ round-trip.
1

    {{⍵÷∨/⍵}⍵,1} 5÷7            ⍝ using gcd.
5 7

    ones ← +\ 10*¯1 to ¯8       ⍝ Gianluigi's examples.
    ones
0.1 0.11 0.111 0.1111 0.11111 0.111111 0.1111111 0.11111111

    ⍉ rational ones
       1        10
      11       100
     111      1000
    1111     10000
   11111    100000
  111111   1000000
 1111111  10000000
11111111 100000000

:If ⎕FR=645                     ⍝ binary FP only

    ⍉ rational ones×9
       9       10
      99      100
     999     1000
    9999    10000
   99999   100000
  999999  1000000
 9999999 10000000
99999998 99999999

:Else
      ⍉rational +\ 10*¯1 to ¯14       ⍝ Gianluigi's examples.
            1                            10
           11                           100
          111                          1000
         1111                         10000
        11111                        100000
       111111                       1000000
      1111111                      10000000
     11111111                     100000000
    111111111                    1000000000
   1111111111                   10000000000
  11111111111                  100000000000
 111111111111                 1000000000000
1111111111111                10000000000000
            0.99999999999999              9
:EndIf

    ,⌿ rational ÷/¨ ⍳10 10
┌────┬───┬────┬───┬───┬───┬────┬───┬────┬────┐
│1 1 │1 2│1 3 │1 4│1 5│1 6│1 7 │1 8│1 9 │1 10│
├────┼───┼────┼───┼───┼───┼────┼───┼────┼────┤
│2 1 │1 1│2 3 │1 2│2 5│1 3│2 7 │1 4│2 9 │1 5 │
├────┼───┼────┼───┼───┼───┼────┼───┼────┼────┤
│3 1 │3 2│1 1 │3 4│3 5│1 2│3 7 │3 8│1 3 │3 10│
├────┼───┼────┼───┼───┼───┼────┼───┼────┼────┤
│4 1 │2 1│4 3 │1 1│4 5│2 3│4 7 │1 2│4 9 │2 5 │
├────┼───┼────┼───┼───┼───┼────┼───┼────┼────┤
│5 1 │5 2│5 3 │5 4│1 1│5 6│5 7 │5 8│5 9 │1 2 │
├────┼───┼────┼───┼───┼───┼────┼───┼────┼────┤
│6 1 │3 1│2 1 │3 2│6 5│1 1│6 7 │3 4│2 3 │3 5 │
├────┼───┼────┼───┼───┼───┼────┼───┼────┼────┤
│7 1 │7 2│7 3 │7 4│7 5│7 6│1 1 │7 8│7 9 │7 10│
├────┼───┼────┼───┼───┼───┼────┼───┼────┼────┤
│8 1 │4 1│8 3 │2 1│8 5│4 3│8 7 │1 1│8 9 │4 5 │
├────┼───┼────┼───┼───┼───┼────┼───┼────┼────┤
│9 1 │9 2│3 1 │9 4│9 5│3 2│9 7 │9 8│1 1 │9 10│
├────┼───┼────┼───┼───┼───┼────┼───┼────┼────┤
│10 1│5 1│10 3│5 2│2 1│5 3│10 7│5 4│10 9│1 1 │
└────┴───┴────┴───┴───┴───┴────┴───┴────┴────┘

⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ The following example gave JMS a bit of a fright:

    P←×/71 73 79 83                     ⍝ product of distinct primes.
    Q←×/89 97 101 103                   ⍝ product of distinct, distinct primes.

    P Q ≡ rational P÷Q                  ⍝ why doesn't this match?
0
    ⍝ The problem is that the function finds a simpler rational number 
    ⍝ within comparison tolerance of the IEEE representation of P÷Q:

    P,Q                                 ⍝ relatively prime numbers.
33984931 89809099

    factors¨P Q                         ⍝ check factors of P and Q
┌───────────┬─────────────┐
│71 73 79 83│89 97 101 103│
└───────────┴─────────────┘

:If ⎕FR=645

        rational P÷Q                    ⍝ simpler tolerably-equal rational.
    7042375 18610288

        factors¨ rational P÷Q           ⍝ factors of simpler rational
    ┌─────────────┬───────────────┐
    │5 5 5 53 1063│2 2 2 2 1163143│
    └─────────────┴───────────────┘
:EndIf

    (P÷Q)=÷/rational P÷Q                ⍝   which is tolerably equal to P÷Q.
1
    ⍝ If we restrict tolerance slightly, P,Q is again our best bet:

    P Q ≡ 1e¯15 rational P÷Q            ⍝ now it matches, phew!
1

⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝

:If ⎕FR=645

    ⍝ ⎕ct-intolerant version for _binary_ floating point:

    ratf←{⎕IO ⎕CT←0                     ⍝ Exact rational from IEEE double.
        digs←16↑⎕D,⎕A                   ⍝ hex digits.
        bits←,⍉2 2 2 2⊤digs⍳hexf ⍵      ⍝ binary floating number.
        split←(⍳⍴bits)∊0 1 12           ⍝ split fields: sign exponent mantissa.
        bsign bexp bmant←split⊂bits     ⍝ bit-vector fields.
        sign←bsign/'¯'                  ⍝ neg sign
        exp←¯1022+2⊥bexp                ⍝ signed numeric binary exponent.
        deco←{↑⍺{⍺+nats ⍺⍺×nats ⍵}/⌽⍵}  ⍝ accurate ⍺-decode.
        top←2 deco 1,bmant              ⍝ numerator.
        bot←2*nats 53-exp               ⍝ denominator.
        sign '',¨top{                   ⍝ rational pair, char vectors à la nats.
            1∊'13579'∊,↑¯1↑¨⍺ ⍵:⍺ ⍵     ⍝ either number is odd: done.
            (⍺÷nats 2)∇ ⍵÷nats 2        ⍝ both even: cancel 2s.
        }bot
    }

        ratf 1234
    ┌────┬─┐
    │1234│1│
    └────┴─┘
        ratf 0.1
    ┌────────────────┬─────────────────┐
    │3602879701896397│36028797018963968│
    └────────────────┴─────────────────┘
        ratf 2*¯16
    ┌─┬─────┐
    │1│65536│
    └─┴─────┘
        ratf ¯0.75
    ┌──┬─┐
    │¯3│4│
    └──┴─┘
:EndIf

Back to: code

Back to: Workspaces