```⍝ 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
```