Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

real to rational number

392 views
Skip to first unread message

krishna...@ccreweb.org

unread,
Apr 18, 2017, 7:49:31 AM4/18/17
to
Rosetta Code has a number of entries for code to converting a (computer representation) of a real number into a rational number, or to the nearest expressible fraction, a/b, where both a and b are integers. There is even a Forth entry!

https://rosettacode.org/wiki/Convert_decimal_number_to_rational

However, it seems like many of the algorithms expressed there are brute force searches, and don't make use of the fundamental theorem of arithmetic to find the suitable integers a and b (though the code which uses library functions may do so).

This particular problem has been in the back of my mind for some time, and it is one that comes up from time to time. For example, in the quantum physics of angular momentum, the Wigner 3-j symbols are real numbers between zero and one, expressible as +/-sqrt(a/b), and if one computes the quantities as real numbers, it would be nice to find (a/b) in an efficient manner. In tables of these symbols, the rational number a/b is expressed as a series of powers of prime numbers and a sign term, e.g. -1 [1 -3 0 -1] represents

r = -sqrt(2/(3^3*7)).

When the finite representation of the real value is given, say to double precision, a smart algorithm to find a and b, or the prime powers representation would be handy. The real to rational code is certainly useful, but I think the algorithms should be able to take advantage of the fact that |r| <= 1. It's an interesting inversion problem.

Incidentally, here is Forth code to compute Wigner 3j symbols -- it is somewhat limited in the range of usable angular momentum quantum numbers, though.

ftp://ccreweb.org/software/kforth/examples/fsl/extras/cg.4th

and accompanying test code,

ftp://ccreweb.org/software/kforth/examples/fsl/extras/cg-test.4th

Krishna

lehs

unread,
Apr 18, 2017, 9:48:13 AM4/18/17
to
To find an algorithm, shouldn't there be a "norm" of some kind? What is to prefer: small a and b or small difference or what?

hughag...@gmail.com

unread,
Apr 18, 2017, 10:06:39 AM4/18/17
to
I have rational numbers in the novice-package. This goes way back to 2010.

They don't work very well because the numerator and denominator are 32-bit, which is pretty small. They'll work a lot better in Straight Forth that requires a 64-bit cell and provides a double-stack that is separate from the single-stack.

I don't know what you mean by a "brute force search." I wrote code that determines the GCD --- isn't that the way that it is always done?

minf...@arcor.de

unread,
Apr 18, 2017, 11:23:27 AM4/18/17
to

krishna...@ccreweb.org

unread,
Apr 18, 2017, 10:09:38 PM4/18/17
to
On Tuesday, April 18, 2017 at 8:48:13 AM UTC-5, lehs wrote:
> Den tisdag 18 april 2017 kl. 13:49:31 UTC+2 skrev krishna...@ccreweb.org:
> > Rosetta Code has a number of entries for code to converting a (computer representation) of a real number into a rational number, or to the nearest expressible fraction, a/b, where both a and b are integers. There is even a Forth entry!
> >
> > https://rosettacode.org/wiki/Convert_decimal_number_to_rational
> >
> > However, it seems like many of the algorithms expressed there are brute force searches, and don't make use of the fundamental theorem of arithmetic to find the suitable integers a and b (though the code which uses library functions may do so).
> >
> > This particular problem has been in the back of my mind for some time, and it is one that comes up from time to time. For example, in the quantum physics of angular momentum, the Wigner 3-j symbols are real numbers between zero and one, expressible as +/-sqrt(a/b), and if one computes the quantities as real numbers, it would be nice to find (a/b) in an efficient manner. In tables of these symbols, the rational number a/b is expressed as a series of powers of prime numbers and a sign term, e.g. -1 [1 -3 0 -1] represents
> >
> > r = -sqrt(2/(3^3*7)).
> >
> > When the finite representation of the real value is given, say to double precision, a smart algorithm to find a and b, or the prime powers representation would be handy. The real to rational code is certainly useful, but I think the algorithms should be able to take advantage of the fact that |r| <= 1. It's an interesting inversion problem.
...
> To find an algorithm, shouldn't there be a "norm" of some kind? What is to prefer: small a and b or small difference or what?

I'm not sure if I understand your question regarding a "norm". There is a unique "a" and "b" which will yield the closest rational number to "r". One assumes the fraction is in simplified form.

For the case of the Wigner 3j symbols, one can restrict the primes included to those from 2 through 19 (this range will cover angular momentum numbers of up to 4). Now, this gives us 8 primes, and their powers may be restricted to the range -4 to +4. The product of the 8 primes, each with a choice of 9 integral powers (including 0), forms our search space for expressing the |r| value as the fraction "a"/"b". However, we should also be able to use the value of |r|, which is between 0 and 1, to restrict the search space.

Krishna

krishna...@ccreweb.org

unread,
Apr 18, 2017, 10:17:07 PM4/18/17
to
Take, for example, the following real number:

r = 7.61904761904762e-02

Find the fraction a/b, so that it agrees to 15 significant digits. It is a simple fraction. Can a double length GCD can do this in a reasonable time?

Krishna

krishna...@ccreweb.org

unread,
Apr 18, 2017, 10:24:02 PM4/18/17
to
On Tuesday, April 18, 2017 at 10:23:27 AM UTC-5, minf...@arcor.de wrote:
...
I'll check it out. Thanks.

Krishna

Paul Rubin

unread,
Apr 18, 2017, 10:40:04 PM4/18/17
to
krishna...@ccreweb.org writes:
> Rosetta Code has a number of entries for code to converting a
> (computer representation) of a real number into a rational number, or
> to the nearest expressible fraction, a/b, where both a and b are
> integers. There is even a Forth entry!

The Forth entry looks pretty naive unfortunately. I'm not sure I
totally understood the problem but I thought the sequence of
lowest-terms rational approximations to a real was given by the
continued fraction sequence.

> r = -sqrt(2/(3^3*7)).
> When the finite representation of the real value is given, say to
> double precision, a smart algorithm to find a and b, or the prime
> powers representation would be handy.

If for some reason you didn't want to do the calculation directly, like
you're on an MCU or something, maybe you could keep a table of the
logarithms of a list of primes. Then you can find -log(r) by adding
suitable multiples of the needed primes, and dividing by 2.

Paul Rubin

unread,
Apr 18, 2017, 10:45:41 PM4/18/17
to
krishna...@ccreweb.org writes:
> r = 7.61904761904762e-02
> Find the fraction a/b, so that it agrees to 15 significant digits.

Wait, that number is 8/105. That was obvious on looking at 1/r.

Paul Rubin

unread,
Apr 18, 2017, 10:49:00 PM4/18/17
to
krishna...@ccreweb.org writes:
> I'll check it out. Thanks.

Do you know about the inverse symbolic calculator?

https://isc.carma.newcastle.edu.au/

You might like to check that out too.

krishna...@ccreweb.org

unread,
Apr 18, 2017, 10:56:11 PM4/18/17
to
On Tuesday, April 18, 2017 at 9:40:04 PM UTC-5, Paul Rubin wrote:
> krishna...@ccreweb.org writes:
> > Rosetta Code has a number of entries for code to converting a
> > (computer representation) of a real number into a rational number, or
> > to the nearest expressible fraction, a/b, where both a and b are
> > integers. There is even a Forth entry!
>
> The Forth entry looks pretty naive unfortunately. ...

Most of the entries in other languages look naive also, in the sense that they appear to be brute force searches.

> I'm not sure I
> totally understood the problem but I thought the sequence of
> lowest-terms rational approximations to a real was given by the
> continued fraction sequence.
>
> > r = -sqrt(2/(3^3*7)).
> > When the finite representation of the real value is given, say to
> > double precision, a smart algorithm to find a and b, or the prime
> > powers representation would be handy.
>
> If for some reason you didn't want to do the calculation directly, like
> you're on an MCU or something, maybe you could keep a table of the
> logarithms of a list of primes. Then you can find -log(r) by adding
> suitable multiples of the needed primes, and dividing by 2.

Just so the problem is clear, I have a double precision value for r, which means I know it to about 16 significant digits. I know r, with infinite precision, is a rational number, but my machine representation is a rounded version to the limited precision. Now, I want to find "a" and "b" where r = a/b. Dividing the floating point representations of a and b, ra and rb, should give me a number equal to r in the machine representation.

Krishna

krishna...@ccreweb.org

unread,
Apr 18, 2017, 10:58:00 PM4/18/17
to
Yes, indeed. Please encode your algorithm ;-)

KM

Pablo Hugo Reda

unread,
Apr 18, 2017, 10:58:24 PM4/18/17
to
I convert from fixed point 16.16 to fraction for a calculator

the complete lib in
https://github.com/phreda4/reda4/blob/master/r4/Lib/frac.txt

the lib has 50 lines, make a fraction of decimal part symplify and sum de integer par, I guess.



::gcd | n1 n2 -- gcd
( 1? )( swap over mod ) drop ;

::fsimp | n1 n2 -- n1 n2
2dup gcd 0? ( drop ; )
>r r / swap r> / swap
-? ( swap neg swap neg ) ;

::fix2f | fix -- n1 d1
dup 16 >> swap $10000 fsimp rot over * rot + swap ;

krishna...@ccreweb.org

unread,
Apr 18, 2017, 11:01:44 PM4/18/17
to
Thanks. Wolfram Alpha will also do this, e.g.

Rationalize(7.61904761904762e-02)

will return 8/105 .

krishna...@ccreweb.org

unread,
Apr 18, 2017, 11:05:41 PM4/18/17
to
On Tuesday, April 18, 2017 at 9:58:24 PM UTC-5, Pablo Hugo Reda wrote:
...
> I convert from fixed point 16.16 to fraction for a calculator
>
> the complete lib in
> https://github.com/phreda4/reda4/blob/master/r4/Lib/frac.txt
>
> the lib has 50 lines, make a fraction of decimal part symplify and sum de integer par, I guess.
>
>
>
> ::gcd | n1 n2 -- gcd
> ( 1? )( swap over mod ) drop ;
>
> ::fsimp | n1 n2 -- n1 n2
> 2dup gcd 0? ( drop ; )
> >r r / swap r> / swap
> -? ( swap neg swap neg ) ;
>
> ::fix2f | fix -- n1 d1
> dup 16 >> swap $10000 fsimp rot over * rot + swap ;

Hi Pablo,

Can you give me an example of using this to solve the originally stated problem?

Krishna

Anton Ertl

unread,
Apr 19, 2017, 1:43:12 AM4/19/17
to
8/105=.076|190476...

where the part after | repeats itself. An exact fraction for r above is

761904761904762/100

which can be simplified by dividing by the GCD to

380952380952381/50

If you allow inexact fractions (I don't see that Rosettacode does),
things get tricky.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2016: http://www.euroforth.org/ef16/

lehs

unread,
Apr 19, 2017, 1:53:44 AM4/19/17
to
I thought the float value represented some kind of measurement with an error, but if the float is regarded as a rational

a/b=N/10^n

then isn't it only to divide N and 10^n with their greatest common divisor d?

a=N/d and b=10^n/d

If there is an intervall and a/b is known to be in this intervall one has to know more. In your case the limitations of the primes and exponents is further conditions such that not any float will have a solution at all. Or am I missunderstanding?

hughag...@gmail.com

unread,
Apr 19, 2017, 2:42:55 AM4/19/17
to
When I said that I have code for GCD, I meant that this is used for adding ratios together --- they have to have a common denominator so you can add the numerators.

For converting a real number into a ratio, you need to use continued fractions. I have this in the novice-package, but I didn't write it --- it was written by Nathaniel Grossman and published in "Forth Dimensions" (Sep/Oct 1984) --- all I did was upgrade his program to work under 32-bit ANS-Forth rather than 16-bit Forth-83.

CF is very slow because ANS-Forth lacks a double-precision division --- this had to be written in high-level Forth --- this is UD/MOD which is in the support code.

Here is an example:

00761904761904762. ok-2
10000000000000000. ok-4
cf
partial-quot numerator denominator
0 0 1
13 1 13
8 8 105
9523809523809 76190476190473 999999999999958
2 152380952380954 2000000000000021
2 380952380952381 5000000000000000 ok

Here is another example:

3141592653589793238. ok-2
1000000000000000000. ok-4
cf
partial-quot numerator denominator
3 3 1
7 22 7
15 333 106
1 355 113
292 103993 33102
1 104348 33215
1 208341 66317
1 312689 99532
2 833719 265381
1 1146408 364913
3 4272943 1360120
1 5419351 1725033
14 80143857 25510582
2 165707065 52746197
1 245850922 78256779
1 411557987 131002976
2 1068966896 340262731
2 2549491779 811528438
1 3618458675 1151791169
12 45970995879 14633022466
1 49589454554 15784813635
3 194739359541 61987463371
1 244328814095 77772277006
6 1660712244111 528621125407
1 1905041058206 606393402413
4 9280876476935 2954194735059
1 11185917535141 3560588137472
18 210627392109473 67044781209555
1 221813309644614 70605369347027
3 876067321043315 278860889250636
5 4602149914861189 1464909815600207
2 10080367150765693 3208680520451050
2 24762884216392575 7882270856502307
1 34843251367158268 11090951376953357
1 59606135583550843 18973222233455664
1 94449386950709111 30064173610409021
16 1570796326794896619 500000000000000000 ok

I still don't know what you mean by a "brute force search."

Paul Rubin

unread,
Apr 19, 2017, 3:41:10 AM4/19/17
to
krishna...@ccreweb.org writes:
> Just so the problem is clear, I have a double precision value for r,
> which means I know it to about 16 significant digits. I know r, with
> infinite precision, is a rational number, but my machine
> representation is a rounded version to the limited precision. Now, I
> want to find "a" and "b" where r = a/b. Dividing the floating point
> representations of a and b, ra and rb, should give me a number equal
> to r in the machine representation.

For the r you gave, it's 8/105 in 64-bit gforth:

7.61904761904762e-02 fvariable r
8e 105e f/ fvariable q
q r f- f.

=> 0. ok

If you want to find the ratio by continued fractions, here's Haskell
code that I just wrote:

import Data.Ratio
import Control.Monad (forM_)

r = 7.61904761904762e-02

-- turn real number into continued fraction sequence
contFrac :: RealFrac a => a -> [Integer]
contFrac x = a : contFrac (1/b) where
(a,b) = properFraction x

-- turn truncated continued fraction into a rational number
unFrac :: Integral a => [a] -> Ratio Integer
unFrac [c] = fromIntegral c
unFrac (c:cs) = fromIntegral c + 1/unFrac cs

-- make rational from first n terms of cont frac of a real
approx :: RealFrac a => Int -> a -> Ratio Integer
approx n x = unFrac . take n . contFrac $ x

-- print first 4 rational approximations of r
main = forM_ [1..4] $ \i -> do
print (approx i r)

The output for the first 4 terms is:

*Main> main
0 % 1
1 % 13
8 % 105
70368744177665 % 923589767331853

You can see the 4th approximant is basically noise. The 5th is much
worse noise, several dozen digits.

krishna...@ccreweb.org

unread,
Apr 19, 2017, 7:43:50 AM4/19/17
to
On Wednesday, April 19, 2017 at 12:53:44 AM UTC-5, lehs wrote:
> I thought the float value represented some kind of measurement with an error, but if the float is regarded as a rational
>
> a/b=N/10^n
>
> then isn't it only to divide N and 10^n with their greatest common divisor d?
>
> a=N/d and b=10^n/d
>

Not exactly, since the last significant digit of our value, r, is rounded. For example, try the gcd procedure with the example,

r = 7.61904761904762e-02

If you attempt gcd(761904761904762, 10^17), you will get 2, and that does not give you the simple fraction.

> If there is an intervall and a/b is known to be in this intervall one has to know more. In your case the limitations of the primes and exponents is further conditions such that not any float will have a solution at all. Or am I missunderstanding?

You are not misunderstanding the problem. One way to visualize it is to consider the solution space as the lattice of points in the first quadrant of the Cartesian grid, with "a" taking on integer values along the y-axis, and "b" taking on the values along the x-axis. We exclude the points which fall on the y-axis, since these represent r = inf.

Now, given the restriction, |r| = a/b <= 1, we can cut the solution space in half, by only considering those lattice points which fall along or below the diagonal, y = x. Given the value of |r|, we should be able to restrict the solution space further.

In the 3j symbol problem, we may use problem-domain specific knowledge, when the solutions for a restricted range of quantum numbers, e.g. for j <= 4, |r| can only take on values which are a product of restricted multiples of a range of restricted primes. That reduces the search space to a finite set of lattice points; however, it is not the same as finding the rational number for arbitrary finite-precision |r|, even with the restriction |r| <= 1.

Krishna

krishna...@ccreweb.org

unread,
Apr 19, 2017, 7:48:10 AM4/19/17
to
Ok. Here, you should truncate the search when the fraction gives the same number of significant digits in r, as input to the problem, which should occur at 8/105.

7.61904761904762e-02 8e 105e f/ f- fs.
0.00000000000000e+00 ok

Krishna

krishna...@ccreweb.org

unread,
Apr 19, 2017, 7:53:13 AM4/19/17
to
On Wednesday, April 19, 2017 at 1:42:55 AM UTC-5, hughag...@gmail.com wrote:
> On Tuesday, April 18, 2017 at 7:17:07 PM UTC-7, krishna...@ccreweb.org wrote:
> > On Tuesday, April 18, 2017 at 9:06:39 AM UTC-5, hughag...@gmail.com wrote:
> > > I have rational numbers in the novice-package. This goes way back to 2010.
> > >
> > > They don't work very well because the numerator and denominator are 32-bit, which is pretty small. They'll work a lot better in Straight Forth that requires a 64-bit cell and provides a double-stack that is separate from the single-stack.
> > >
> > > I don't know what you mean by a "brute force search." I wrote code that determines the GCD --- isn't that the way that it is always done?
> >
> > Take, for example, the following real number:
> >
> > r = 7.61904761904762e-02
> >
> > Find the fraction a/b, so that it agrees to 15 significant digits. It is a simple fraction. Can a double length GCD can do this in a reasonable time?
> >
> > Krishna
>
> When I said that I have code for GCD, I meant that this is used for adding ratios together --- they have to have a common denominator so you can add the numerators.
>
> For converting a real number into a ratio, you need to use continued fractions. I have this in the novice-package, but I didn't write it --- it was written by Nathaniel Grossman and published in "Forth Dimensions" (Sep/Oct 1984) --- all I did was upgrade his program to work under 32-bit ANS-Forth rather than 16-bit Forth-83.
>
> CF is very slow because ANS-Forth lacks a double-precision division --- this had to be written in high-level Forth --- this is UD/MOD which is in the support code.
>
> Here is an example:
>
> 00761904761904762. ok-2
> 10000000000000000. ok-4
> cf
> partial-quot numerator denominator
> 0 0 1
> 13 1 13
> 8 8 105
> ...

Very good. The continued fraction should truncate when we have achieve the same number of significant digits specified for r, in this case, 15. With regard to your question about what constitutes a brute-force search, please see my reply to lehs.

Krishna

Pablo Hugo Reda

unread,
Apr 19, 2017, 8:30:24 AM4/19/17
to
Krishna

I found a bug!,not work for number with not zero integer part, the code for test is

:main
show clrscr

0.6190 | 7.619 not work
dup "%f " print | print fixpoint
fix2f 2dup | convert to fraction
swap "%d/%d" print | print in fraction
16 <</ " %f" print | back to fixed point

'exit >esc<
cminiflecha ;

I don't remenber how code this.
for 0.619 work ok but for 7.619 give me 14.619, the integer part is doubled!
sorry.

Pablo Hugo Reda

unread,
Apr 19, 2017, 8:35:26 AM4/19/17
to
well try this and work:

::fix2f | fix -- n1 d1
dup 16 >> swap $ffff and $10000 fsimp rot over * rot + swap ;

clear the fractional part for make the fraction..
remenber my fixed point number are 16.16, not great precision.

Pablo Hugo Reda

unread,
Apr 19, 2017, 8:41:56 AM4/19/17
to
0.0761
dup "%f " print
fix2f 2dup
swap "%d/%d" print
16 <</ " %f" print

give me
0.0760 4987/65536 0.0760



hughag...@gmail.com

unread,
Apr 19, 2017, 2:30:25 PM4/19/17
to
On Wednesday, April 19, 2017 at 12:41:10 AM UTC-7, Paul Rubin wrote:
> If you want to find the ratio by continued fractions, here's Haskell
> code that I just wrote:

Way back in 1984 when I was learning Forth, I was very impressed by */ that I read about in: "Starting Forth." Of course, I wondered how the ratios were obtained. What if you need a ratio that isn't listed in the book's short list of common ratios? Most likely, Charles Moore wrote a program in Fortran to calculate the ratios. That is a sad commentary on Forth that the inventor of Forth has to switch to Fortran to obtain the ratios that he uses in Forth with his */ that is arguably one of the coolest features of Forth (and which is lacking in Fortran). Now I see that you have written a program in Haskell to calculate the ratios. All the Forth enthusiasts jump to another language when they encounter flaws in Forth.

Later that year, after my high-school graduation, an article appeared in "Forth Dimensions" that described how to write continued fractions in Forth. This code required significant amounts of support, including writing UD/MOD in high-level Forth. At the time, everybody knew that Forth-83 had serious problems due to the fact that Charles Moore had been kicked out of Forth Inc. in 1982 and hence Forth-83 was written by Elizabeth Rather. The expectation however, was that a new standard would be coming soon --- a standard designed by Forth programmers, rather than a salesperson. A lot of time passed, and then ANS-Forth came out in 1994, but it was no better than Forth-83. Later on, in the 21st century, I upgraded the 1984 program to run under ANS-Forth --- but ANS-Forth still has the same problems as Forth-83 --- the only difference is that ANS-Forth is available on 32-bit computers.

hughag...@gmail.com

unread,
Apr 19, 2017, 2:32:05 PM4/19/17
to
You are right. I should make it stop after it has achieved maximum precision.

rickman

unread,
Apr 19, 2017, 3:36:45 PM4/19/17
to
On 4/18/2017 9:48 AM, lehs wrote:
> Den tisdag 18 april 2017 kl. 13:49:31 UTC+2 skrev krishna...@ccreweb.org:
>> Rosetta Code has a number of entries for code to converting a (computer representation) of a real number into a rational number, or to the nearest expressible fraction, a/b, where both a and b are integers. There is even a Forth entry!
>>
>> https://rosettacode.org/wiki/Convert_decimal_number_to_rational
>>
>> However, it seems like many of the algorithms expressed there are brute force searches, and don't make use of the fundamental theorem of arithmetic to find the suitable integers a and b (though the code which uses library functions may do so).
>>
>> This particular problem has been in the back of my mind for some time, and it is one that comes up from time to time. For example, in the quantum physics of angular momentum, the Wigner 3-j symbols are real numbers between zero and one, expressible as +/-sqrt(a/b), and if one computes the quantities as real numbers, it would be nice to find (a/b) in an efficient manner. In tables of these symbols, the rational number a/b is expressed as a series of powers of prime numbers and a sign term, e.g. -1 [1 -3 0 -1] represents
>>
>> r = -sqrt(2/(3^3*7)).
>>
>> When the finite representation of the real value is given, say to double precision, a smart algorithm to find a and b, or the prime powers representation would be handy. The real to rational code is certainly useful, but I think the algorithms should be able to take advantage of the fact that |r| <= 1. It's an interesting inversion problem.
>>
>> Incidentally, here is Forth code to compute Wigner 3j symbols -- it is somewhat limited in the range of usable angular momentum quantum numbers, though.
>>
>> ftp://ccreweb.org/software/kforth/examples/fsl/extras/cg.4th
>>
>> and accompanying test code,
>>
>> ftp://ccreweb.org/software/kforth/examples/fsl/extras/cg-test.4th
>>
>> Krishna
>
> To find an algorithm, shouldn't there be a "norm" of some kind? What is to prefer: small a and b or small difference or what?

Simplest form. Here is my solution.

: Rational ( F: f1 -- ) ( -- n1 n2 ) FDROP 1 1 ;

It may not have the best accuracy, but it is hard to beat for simplest
form.

--

Rick C

rickman

unread,
Apr 19, 2017, 3:41:36 PM4/19/17
to
I don't understand all of the language you are using, but there are an
infinite number of integers and the solution can be found arbitrarily
close to any real value by finding larger value integers. To my
understanding there is *no* single solution unless you restrict the
magnitude of the integers you use.

--

Rick C

Paul Rubin

unread,
Apr 19, 2017, 4:03:27 PM4/19/17
to
rickman <gnu...@gmail.com> writes:
> I don't understand all of the language you are using, but there are an
> infinite number of integers and the solution can be found arbitrarily
> close to any real value by finding larger value integers. To my
> understanding there is *no* single solution unless you restrict the
> magnitude of the integers you use.

There's two questions being conflated:

1) given a floating point number x, find the smallest pair of integers
a,b such that a/b == x to the same precision that x is given in.

2) given an irrational number x, find rational approximations that are
as close as possible to x given their size. E.g. for pi, the
approximants are 3/1, 22/7, 333/106, 355/113, 103993/33102,
104348/33215, 208341/66317, 312689/99532, 833719/265381,
1146408/364913, etc.

Both of these are done with the continued fraction algorithm that I
posted. It helps if you have bignum arithmetic for this sort of thing.

Rudy Velthuis

unread,
Apr 19, 2017, 7:16:06 PM4/19/17
to
krishna...@ccreweb.org wrote:

> Rosetta Code has a number of entries for code to converting a
> (computer representation) of a real number into a rational number, or
> to the nearest expressible fraction, a/b, where both a and b are
> integers. There is even a Forth entry!

What a coincidence! I just looked at that page only a few days ago,
looking for optimized versions of my code to convert BigDecimals to
BigRationals (not in Forth, though, in Delphi).

--
Rudy Velthuis http://www.rvelthuis.de

"He who hesitates is a damned fool." -- Mae West (1892-1980)

Rudy Velthuis

unread,
Apr 19, 2017, 7:44:10 PM4/19/17
to
krishna...@ccreweb.org wrote:

> On Tuesday, April 18, 2017 at 8:48:13 AM UTC-5, lehs wrote:
> > Den tisdag 18 april 2017 kl. 13:49:31 UTC+2 skrev
> > krishna...@ccreweb.org:
> > > Rosetta Code has a number of entries for code to converting a
> > > (computer representation) of a real number into a rational
> > > number, or to the nearest expressible fraction, a/b, where both a
> > > and b are integers. There is even a Forth entry!
> > >
> > > https://rosettacode.org/wiki/Convert_decimal_number_to_rational
> > >
> > > However, it seems like many of the algorithms expressed there are
> > > brute force searches, and don't make use of the fundamental
> > > theorem of arithmetic to find the suitable integers a and b
> > > (though the code which uses library functions may do so).
> > >
> > > This particular problem has been in the back of my mind for some
> > > time, and it is one that comes up from time to time. For example,
> > > in the quantum physics of angular momentum, the Wigner 3-j
> > > symbols are real numbers between zero and one, expressible as
> > > +/-sqrt(a/b), and if one computes the quantities as real numbers,
> > > it would be nice to find (a/b) in an efficient manner. In tables
> > > of these symbols, the rational number a/b is expressed as a
> > > series of powers of prime numbers and a sign term, e.g. -1 [1 -3
> > > 0 -1] represents
> > >
> > > r = -sqrt(2/(3^3*7)).
> > >
> > > When the finite representation of the real value is given, say to
> > > double precision, a smart algorithm to find a and b, or the prime
> > > powers representation would be handy. The real to rational code
> > > is certainly useful, but I think the algorithms should be able to
> > > take advantage of the fact that |r| <= 1. It's an interesting
> > > inversion problem.
> ...
> > To find an algorithm, shouldn't there be a "norm" of some kind?
> > What is to prefer: small a and b or small difference or what?
>
> I'm not sure if I understand your question regarding a "norm". There
> is a unique "a" and "b" which will yield the closest rational number
> to "r".

Since a real is a (finite) floating point number, probably a double
precision (64 bit) IEEE-754 binary floating point number, the
absolutely *closest* approximation is simply the significand as integer
divided by the appropriate power of 2, because that CONVERSION is exact.

Even if the real is a decimal representation like 1.234, then the
*best* approximation is 1234/1000.

But generally, people want 0.33333333333333 to be turned into something
like 1/3 and not into 33333333333333/100000000000000. That is probably
what lehs means: what is the maximum number of digits (or bits) in the
dividend, or what is the maximum difference in digits (or bits) between
dividend or divisior, or what is the minimum or maximum epsilon used
for such a conversion? In other words, how do you define the "best"
appproximation (what norms do you use), if you consider the fact that
neither decimal nor binary representations can always properly
represent rational numbers.

Or, if you want to use continued fractions, how many levels deep do you
go before you quit, etc.?

--
Rudy Velthuis http://www.rvelthuis.de

"I hit him to get his attention. I shot him to calm him down. I
killed him to reason with him."
-- Henry Rollins

Paul Rubin

unread,
Apr 19, 2017, 10:30:36 PM4/19/17
to
"Rudy Velthuis" <newsg...@rvelthuis.de> writes:
> Since a real is a (finite) floating point number,

By a "real" I meant a mathematical real like 1/pi, not a computer
floating point number.

> Or, if you want to use continued fractions, how many levels deep do you
> go before you quit, etc.?

When you decide that the approximation is close enough, or that the
fraction has gotten too ugly.

krishna...@ccreweb.org

unread,
Apr 19, 2017, 10:39:21 PM4/19/17
to
On Wednesday, April 19, 2017 at 7:41:56 AM UTC-5, Pablo Hugo Reda wrote:
...
> > well try this and work:
> >
> > ::fix2f | fix -- n1 d1
> > dup 16 >> swap $ffff and $10000 fsimp rot over * rot + swap ;
> >
> > clear the fractional part for make the fraction..
> > remenber my fixed point number are 16.16, not great precision.
>
> 0.0761
> dup "%f " print
> fix2f 2dup
> swap "%d/%d" print
> 16 <</ " %f" print
>
> give me
> 0.0760 4987/65536 0.0760

I'm not sure I understand how this works; will have to study it. Thanks.

Krishna

krishna...@ccreweb.org

unread,
Apr 19, 2017, 10:42:44 PM4/19/17
to
On Wednesday, April 19, 2017 at 6:16:06 PM UTC-5, Rudy Velthuis wrote:
> krishna...@ccreweb.org wrote:
>
> > Rosetta Code has a number of entries for code to converting a
> > (computer representation) of a real number into a rational number, or
> > to the nearest expressible fraction, a/b, where both a and b are
> > integers. There is even a Forth entry!
>
> What a coincidence! I just looked at that page only a few days ago,
> looking for optimized versions of my code to convert BigDecimals to
> BigRationals (not in Forth, though, in Delphi).
>...

The Forth version at Rosetta Code is not my style, and, I think, perhaps a poor representative for Forth 2011. The use of locals is overdone, perhaps to make programmers from other languages feel more comfortable. Anyway, below is my Forth-94 (aka ANS Forth) version.

Krishna

--

\ rational.4th
\
\ Brute force search, optimized to search only
\ within integer bounds surrounding target.
\
\ Requires:
\ ans-words.4th ( for kForth )
\
\ From Rosetta code:
\ https://rosettacode.org/wiki/Convert_decimal_number_to_rational#Forth
\
\ Examples:
\
\ 1.618033988e 100 RealToRational swap . . 144 89
\ 3.14159e 1000 RealToRational swap . . 355 113
\ 2.71828e 1000 RealToRational swap . . 1264 465
\ 0.9054054e 100 RealToRational swap . . 67 74

fvariable besterror
0 value numtor
0 value denom
0 value realscale
false value neg?

[undefined] ftrunc>s [IF]
: ftrunc>s ( r -- s ) ftrunc f>d d>s ;
[THEN]

: RationalError ( |r| num den -- rerror ) >r s>f r> s>f f/ f- fabs ;

: RealToRational ( r den_limit -- numerator denominator )
0 to numtor 1 to denom
9999999e besterror f! \ very large error that will surely
\ be improved upon

>r \ r --
fdup f0< to neg? \ save sign for later
fabs

\ realscale helps set integer bounds around target
fdup ftrunc>s 1+ to realscale

\ search through possible denominators ( 1 to denlimit)
r> 1+ 1 ?DO
\ |r| --
\ search through numerator within integer limits bounding
\ the real, e.g. for 3.1419e search only between 3 and 4
I realscale * I realscale 1- * ?DO
fdup I J RationalError
fdup besterror f@ f< IF
besterror f!
I to numtor J to denom
ELSE fdrop
THEN
LOOP
LOOP
fdrop

numtor neg? IF negate THEN denom
;

Rudy Velthuis

unread,
Apr 20, 2017, 1:08:51 PM4/20/17
to
Paul Rubin wrote:

> "Rudy Velthuis" <newsg...@rvelthuis.de> writes:
> > Since a real is a (finite) floating point number,
>
> By a "real" I meant a mathematical real like 1/pi, not a computer
> floating point number.

Then I don't quite understand it. If you already have a mathematical
real, then what is the problem?

>
> > Or, if you want to use continued fractions, how many levels deep do
> > you go before you quit, etc.?
>
> When you decide that the approximation is close enough, or that the
> fraction has gotten too ugly.

That is probably one of the possible "norm"s lehs refers to.

--
Rudy Velthuis http://www.rvelthuis.de

"Be tolerant of the human race. Your whole family belongs to it
-- and some of your spouse's family too." -- Anonymous.

Rudy Velthuis

unread,
Apr 20, 2017, 1:15:06 PM4/20/17
to
krishna...@ccreweb.org wrote:

> The Forth version at Rosetta Code is not my style, and, I think,
> perhaps a poor representative for Forth 2011. The use of locals is
> overdone, perhaps to make programmers from other languages feel more
> comfortable. Anyway, below is my Forth-94 (aka ANS Forth) version.

<snip>

> fvariable besterror
> 0 value numtor
> 0 value denom
> 0 value realscale
> false value neg?

You say the use of locals in the Rosetta version is overdone but you
don't mind using global variables/values instead?

--
Rudy Velthuis http://www.rvelthuis.de

"I've just learned about his illness. Let's hope it's nothing
trivial." -- Irvin S. Cobb

Rudy Velthuis

unread,
Apr 20, 2017, 1:26:30 PM4/20/17
to
Paul Rubin wrote:

> rickman <gnu...@gmail.com> writes:
> > I don't understand all of the language you are using, but there are
> > an infinite number of integers and the solution can be found
> > arbitrarily close to any real value by finding larger value
> > integers. To my understanding there is no single solution unless
> > you restrict the magnitude of the integers you use.
>
> There's two questions being conflated:
>
> 1) given a floating point number x, find the smallest pair of integers
> a,b such that a/b == x to the same precision that x is given in.

That is what I thought too, but apparently he means "mathematical
reals", not "computer floating point numbers".


--
Rudy Velthuis http://www.rvelthuis.de

"In law a man is guilty when he violates the rights of another.
In ethics he is guilty if he only thinks of doing so."
-- Immanuel Kant

Albert van der Horst

unread,
Apr 20, 2017, 2:14:23 PM4/20/17
to
In article <718428df-9808-4765...@googlegroups.com>,
<krishna...@ccreweb.org> wrote:
>On Tuesday, April 18, 2017 at 9:40:04 PM UTC-5, Paul Rubin wrote:
>> krishna...@ccreweb.org writes:
>> > Rosetta Code has a number of entries for code to converting a
>> > (computer representation) of a real number into a rational number, or
>> > to the nearest expressible fraction, a/b, where both a and b are
>> > integers. There is even a Forth entry!
>>=20
>> The Forth entry looks pretty naive unfortunately. ...
>
>Most of the entries in other languages look naive also, in the sense that t=
>hey appear to be brute force searches.
>
>> I'm not sure I
>> totally understood the problem but I thought the sequence of
>> lowest-terms rational approximations to a real was given by the
>> continued fraction sequence.
>>=20
>> > r =3D -sqrt(2/(3^3*7)).
>> > When the finite representation of the real value is given, say to
>> > double precision, a smart algorithm to find a and b, or the prime
>> > powers representation would be handy.=20
>>=20
>> If for some reason you didn't want to do the calculation directly, like
>> you're on an MCU or something, maybe you could keep a table of the
>> logarithms of a list of primes. Then you can find -log(r) by adding
>> suitable multiples of the needed primes, and dividing by 2.
>
>Just so the problem is clear, I have a double precision value for r, which =
>means I know it to about 16 significant digits. I know r, with infinite pre=
>cision, is a rational number, but my machine representation is a rounded ve=
>rsion to the limited precision. Now, I want to find "a" and "b" where r =3D=
> a/b. Dividing the floating point representations of a and b, ra and rb, sh=
>ould give me a number equal to r in the machine representation.
>


Let's see ...

~/PROJECT/ciforth$ lina64 -e
AMDX86 ciforth beta 2017Apr18
...
COPYRIGHT (c) ...
This program is free ... redistribute .. blabla.

WANT -fp-
...
OK
FINIT
OK
HEX PI
OK
FDUP 100 F.R
3.243F6A8885A308D00000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000_0 OK
\ I meant 100 not 256 ...
3.243F6A8885A308D .S

S[ 3243F6A8885A308D 0 ] OK
\ Fits in a single.
----------
So apparently
3243F6A8885A308D : 1000000000000000
is the ratio (for this particular fp : Intel 8087)

Where is the beef?

The refusal to use hex for floats make them seem sooooo mysterious.
(Insisting on E for exponent while in 1968 we knew better.)

\ Continuing:
3243F6A8885A308D 1000000000000000 DECIMAL
OK
BEGIN OVER /MOD . DUP WHILE SWAP REPEAT
0 3 7 15 1 292 1 1 1 2 1 3 1 14 2 1 1 2 2 1 1 2 3 1 1 6 1 1 5 7
1 1 23 2 6 1 5 3 1 2 OK
.
0 OK

There you have your coefficients, the corresponding continued fraction
will represent the computer fp exactly, because it is a rational.

(Unless you're clairvoyant and *know* that number is supposed to be
the mathematical pi, that is all their is to it.
If you know it is pi, you can find an equally good approximation of pi
with half the coefficients.
You cannot find a better approximation for
3243F6A8885A308D / 1000000000000000
because it is exact. )

>Krishna
> =20
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Paul Rubin

unread,
Apr 20, 2017, 2:46:42 PM4/20/17
to
"Rudy Velthuis" <newsg...@rvelthuis.de> writes:
> Then I don't quite understand it. If you already have a mathematical
> real, then what is the problem?

You want to find a rational approximation to your mathematical real.
E.g. suppose your real is pi. You could use 31/10 as an approximation,
but it turns out 22/7 is closer. If you want even better, 355/113 is
extremely close. How do you find these fractions? You could do a
brute force search through possible denominators, but there's a much
faster algorithm using continued fractions that I posted.

hughag...@gmail.com

unread,
Apr 20, 2017, 5:29:15 PM4/20/17
to
On Wednesday, April 19, 2017 at 1:03:27 PM UTC-7, Paul Rubin wrote:
> rickman <gnu...@gmail.com> writes:
> There's two questions being conflated:
>
> 1) given a floating point number x, find the smallest pair of integers
> a,b such that a/b == x to the same precision that x is given in.
>
> 2) given an irrational number x, find rational approximations that are
> as close as possible to x given their size. E.g. for pi, the
> approximants are 3/1, 22/7, 333/106, 355/113, 103993/33102,
> 104348/33215, 208341/66317, 312689/99532, 833719/265381,
> 1146408/364913, etc.
>
> Both of these are done with the continued fraction algorithm that I
> posted. It helps if you have bignum arithmetic for this sort of thing.

You don't need bignum arithmetic for this sort of thing, and using it will result in an unduly slow program.

You just need to be able to do a division at twice the precision that you want your result to be. Your resulting ratio is for use in ordinary Forth arithmetic and this doesn't use bignums:
-------------------------------------------------------------------------

\ The following are some ways of approximating pi, all of which were derived from the CF.4th program:

: pi* ( s -- s-result ) \ signed single-precision
1068966896 340262731 */ ;

: upi* ( u -- u-result ) \ unsigned single-precision
3618458675 1151791169 u*/ ;

: dpi* ( d -- d-result ) \ signed double-precision
1068966896 340262731 m*/ ;

: udpi* ( ud -- ud-result ) \ unsigned double-precision
3083975227 1963319607 ut*/ d2* ;

\ Note that UDPI* multiplies by pi/2 and then multiplies the result by 2.
\ This trick provides better precision sometimes.

krishna...@ccreweb.org

unread,
Apr 20, 2017, 6:11:16 PM4/20/17
to
On Thursday, April 20, 2017 at 12:15:06 PM UTC-5, Rudy Velthuis wrote:
> krishna...@ccreweb.org wrote:
> ...
>
> > fvariable besterror
> > 0 value numtor
> > 0 value denom
> > 0 value realscale
> > false value neg?
>
> You say the use of locals in the Rosetta version is overdone but you
> don't mind using global variables/values instead?
> ..

Nope, I don't mind, as long as I have no concerns about re-entrancy or name masking. This is Forth and I can redefine those "globals" without affecting the code which relies on them. But, I don't want to divert the present thread into a debate on the merits of locals versus "globals" versus use of the stack -- that has been debated numerous times over the years in c.l.f. I'm not opposed to using locals in moderation, and, in fact, I think several of the quantities such as the numerator and denominator are best kept as locals in this code. However, assigning a local to the real number argument leads to a lot of unneeded visual clutter.

Krishna

krishna...@ccreweb.org

unread,
Apr 20, 2017, 6:23:52 PM4/20/17
to
On Thursday, April 20, 2017 at 1:14:23 PM UTC-5, Albert van der Horst wrote:
...
>
> S[ 3243F6A8885A308D 0 ] OK
> \ Fits in a single.
> ----------
> So apparently
> 3243F6A8885A308D : 1000000000000000
> is the ratio (for this particular fp : Intel 8087)
>

What does "S[ 3243F6A8885A308D 0 ]" do?

> ...
> \ Continuing:
> 3243F6A8885A308D 1000000000000000 DECIMAL
> OK
> BEGIN OVER /MOD . DUP WHILE SWAP REPEAT
> 0 3 7 15 1 292 1 1 1 2 1 3 1 14 2 1 1 2 2 1 1 2 3 1 1 6 1 1 5 7
> 1 1 23 2 6 1 5 3 1 2 OK
> .
> 0 OK
>
> There you have your coefficients, the corresponding continued fraction
> will represent the computer fp exactly, because it is a rational.
>
> (Unless you're clairvoyant and *know* that number is supposed to be
> the mathematical pi, that is all their is to it.
> If you know it is pi, you can find an equally good approximation of pi
> with half the coefficients.
> You cannot find a better approximation for
> 3243F6A8885A308D / 1000000000000000
> because it is exact. )

It is "exact" in the sense of the finite precision machine representation. However, are you sure there is no other ratio, using smaller integers, which will you give you the "exact" real number to the same precision?

In the previous example I gave,

r = 7.61904761904762e-02

one can certainly write it as the ratio of integers, 761904781904762 : 100000000000000000 . However, the smallest pair of integers which will yield the same precision (as written above) is 8 : 105. The continued fraction can be truncated at the point where the rational approximation no longer provides any further improvement in error.

In some instances, such as for the squares of the Wigner 3-j symbols, we know in advance that the results are rational numbers. However, on a computer, they are often calculated in such a way to give a floating point number and it is difficult to find the corresponding rational number by hand.

Krishna

hughag...@gmail.com

unread,
Apr 20, 2017, 6:49:53 PM4/20/17
to
On Thursday, April 20, 2017 at 3:11:16 PM UTC-7, krishna...@ccreweb.org wrote:
> I think several of the quantities such as the numerator and denominator are best kept as locals in this code. However, assigning a local to the real number argument leads to a lot of unneeded visual clutter.

One of the many blunders of ANS-Forth was to make locals with with TO --- it would have been much better to make the local provide an address and then use @ and ! on that address --- if the local is big enough to contain a double or a float, then D@ and D! as well as F@ and F! can also be used on the local's address.

Elizabeth Rather says:
----------------------------------------------------------------
I hate locals :-)
----------------------------------------------------------------

Could this be why locals were completely f'ed up in ANS-Forth? What I described above, with the local providing an address and being big enough to hold any primitive data-type, is obvious. Only a low-grade moron would use TO and consequently limit locals to only single-cell values. Also, Elizabeth Rather got the parameters for LOCALS| backwards, which also indicates the intelligence level of a low-grade moron.

Elizabeth Rather should be kicked out of the Forth community. Being a low-grade moron would be okay if she were willing to learn, but claiming to be the "leading expert" of the Forth community implies that she is unwilling to learn --- so, she has to go! --- there is no other way for Forth to ever be taken seriously in the real world.

Alex

unread,
Apr 20, 2017, 7:20:29 PM4/20/17
to
On 4/20/2017 23:49, hughag...@gmail.com wrote:
> On Thursday, April 20, 2017 at 3:11:16 PM UTC-7,
> krishna...@ccreweb.org wrote:
>> I think several of the quantities such as the numerator and
>> denominator are best kept as locals in this code. However,
>> assigning a local to the real number argument leads to a lot of
>> unneeded visual clutter.
>
> One of the many blunders of ANS-Forth was to make locals with with TO
> --- it would have been much better to make the local provide an
> address and then use @ and ! on that address --- if the local is big
> enough to contain a double or a float, then D@ and D! as well as F@
> and F! can also be used on the local's address.

(direct quote) Gforth currently supports cells (W:, W^), doubles (D:,
D^), floats (F:, F^) and characters (C:, C^) in two flavours: a
value-flavoured local (defined with W:, D: etc.) produces its value and
can be changed with TO. A variable-flavoured local (defined with W^
etc.) produces its address (which becomes invalid when the variable's
scope is left).

https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Gforth-locals.html

You could write up an RfD to get this in the standard. Could, but won't.

>
> Elizabeth Rather says:
> ---------------------------------------------------------------- I
> hate locals :-)
> ----------------------------------------------------------------
>

As do I. I just put my Forth up on github, and you'll find very little
use of locals. They're largely a distraction with a limited number of
use cases.

--
Alex

krishna...@ccreweb.org

unread,
Apr 20, 2017, 7:22:30 PM4/20/17
to
On Thursday, April 20, 2017 at 5:49:53 PM UTC-5, hughag...@gmail.com wrote:

> One of the many blunders of ANS-Forth was to make locals with with TO --- it would have been much better to make the local provide an address and then use @ and ! on that address --- if the local is big enough to contain a double or a float, then D@ and D! as well as F@ and F! can also be used on the local's address.
> ....
[crap clipped]

Your unwarranted and personal rants against Elizabeth Rather completely discredit any positive contributions you make to discussion topics in this newsgroup.

Goodbye.

krishna...@ccreweb.org

unread,
Apr 20, 2017, 9:44:32 PM4/20/17
to
On Wednesday, April 19, 2017 at 2:36:45 PM UTC-5, rickman wrote:
...
>
> Simplest form. Here is my solution.
>
> : Rational ( F: f1 -- ) ( -- n1 n2 ) FDROP 1 1 ;
>
> It may not have the best accuracy, but it is hard to beat for simplest
> form.
> ...

That approximation and throw in an RC clock oscillator -- well, you get what you pay for ;-)

Krishna



krishna...@ccreweb.org

unread,
Apr 20, 2017, 9:49:51 PM4/20/17
to
On Thursday, April 20, 2017 at 6:20:29 PM UTC-5, Alex wrote:
> ... I just put my Forth up on github, and you'll find very little
> use of locals. They're largely a distraction with a limited number of
> use cases.
>

I've not implemented locals in kForth, nor do I feel any compulsion to do so.

Krishna

Paul Rubin

unread,
Apr 20, 2017, 9:52:54 PM4/20/17
to
krishna...@ccreweb.org writes:
> In some instances, such as for the squares of the Wigner 3-j symbols,
> we know in advance that the results are rational numbers. However, on
> a computer, they are often calculated in such a way to give a floating
> point number and it is difficult to find the corresponding rational
> number by hand.

You could use mpfr and do the calculation in exact rational arithmetic
from the beginning.

lehs

unread,
Apr 20, 2017, 11:49:20 PM4/20/17
to
Den torsdag 20 april 2017 kl. 19:08:51 UTC+2 skrev Rudy Velthuis:
> Paul Rubin wrote:
>
> > "Rudy Velthuis" <newsg...@rvelthuis.de> writes:
> > > Since a real is a (finite) floating point number,
> >
> > By a "real" I meant a mathematical real like 1/pi, not a computer
> > floating point number.
>
> Then I don't quite understand it. If you already have a mathematical
> real, then what is the problem?
>
> >
> > > Or, if you want to use continued fractions, how many levels deep do
> > > you go before you quit, etc.?
> >
> > When you decide that the approximation is close enough, or that the
> > fraction has gotten too ugly.
>
> That is probably one of the possible "norm"s lehs refers to.
>
> --
> Rudy Velthuis http://www.rvelthuis.de
>

I agree. It feels wrong to consider a hypothetical measure as an exact number and too limited to find an exact reduced ratio of that number. Either the algorithm have to suggest a suite of rationals for manual selection or there should be further conditions for the algorithm in order to letting it try to find a unique ratio pair.

The measure 1.234 (without explicit error estimation) could be considered as an intervall [1.2335,1.2345). And in most cases lower a,b with a/b in the intervall are more interesting than higher a,b. In this case it's possible to make an algorithm that calculate the lowest pair (a,b) in the intervall. But of cource, if that ratio a/b is very close to a limit of the intervall one might consider more centered ratios, even if those have higher a,b.

In the case when only some numbers are allowed for a and b, the algorithm must be able to filter the search.

s" c:/ans-forth-lib/numbertheory.4th" included
\ https://github.com/Lehs/ANS-Forth-libraries

fvariable dev

: reduce-ratio \ a b -- a' b'
2dup ugcd tuck / -rot / ;

: finter \ f f' f" -- flag f<f"<f'
ftuck f> f< and ;

: fmean \ f1 f2 -- f3
f+ 2e f/ ;

\ f'>f>1, f<a/b<f'
: fratio \ f f' m n -- f" a b
false locals| flag n m |
-1 m
do i n
do fover fover j s>f i s>f f/ finter \ f f'
if fover fover fmean \ f f' fm
j s>f i s>f f/ fover f- fabs fdup dev f! \ f f' fm f1
fswap m s>f n s>f f/ f- fabs f< \ f f' f1<f2
if j to m
i to n
true to flag leave
then
then
loop flag if leave then
loop fdrop fdrop
n m reduce-ratio dev f@ ;

Given a float interval (f,f') and two integers m>n FRATIO gives the first integers a>b such that f<a/b<f' and such that f"=|fm-a/b|<|fm-m/n|, where fm is the mean of f and f'.

Here a/b>1. If x<1 examine 1/x and it's interval of accuracy:

1/r^2=a/b, in the example with the Wigner 3-j symbols.

This can be used to find a solution with wanted accuracy and divisibility.

hughag...@gmail.com

unread,
Apr 21, 2017, 1:02:53 AM4/21/17
to
Goodbye to you --- brown-noser!

Elizabeth Rather said that she hated locals, and locals were completely screwed up in ANS-Forth --- she purposely sabotaged the definition of locals in ANS-Forth --- she wanted everybody in the Forth community to hate locals too, and believe that locals are inherently screwed up.

We see the same thing now in Forth-200x. Stephen Pelc and Elizabeth Rather have both said that they don't know what quotations are for, or how to implement them. Rather than learn anything about the subject, they want a fake implementation to become the standard --- they want everybody in the Forth community to hate quotations too, and believe that quotations are inherently screwed up.

I'm never going to brown-nose the committee! ANS-Forth is a cult --- being an ANS-Forth "programmer" requires willful ignorance --- you are required to know less than your "leading expert" on the subject of programming, and she really knows nothing. Becoming an ANS-Forth programmer is very much like getting a lobotomy --- you have to wipe all knowledge of computer science from your brain.

This is from Stephen Pelc's article on quotations:
http://newsgroups.derkeiler.com/Archive/Comp/comp.lang.forth/2012-07/msg00791.html
-----------------------------------
Aside from looking obscure and clever and satisfying the "[x] can do it, why not Forth?" test, what on earth does this buy you?
-----------------------------------
Elizabeth Rather, as well as multiple ANS-Forth sycophants, have quoted Stephen Pelc's article on comp.lang.forth., and the RfD is is pretty much a line-by-line copy of the article. They are ignoramuses! What is the point of writing an article about a subject and then admitting in the article that you don't know anything about the subject? Ignoramuses are people who are not only ignorant of a subject, but are proud of their ignorance. Stephen Pelc wrote this article because he was proud of his ignorance, and he wanted to make this public so the ANS-Forth sycophants would know that they are supposed to hate quotations too --- now all of the Forth-200x mailing-list brown-nosers obediently hate quotations --- even when I show them code that works in VFX and SwiftForth and allows the quotation to have access to the parent function's locals, they continue to say that this is impossible.

I'm always willing to learn new concepts, and become a better programmer. I don't think that it is a good idea to get stuck in some time period from the past (for Elizabeth Rather and the ANS-Forth cult, this is the early 1970s). I suppose that it feels comforting to the ANS-Forth cult members that they will never be challenged to learn anything new, and so long as they continue to be loyal to their "leading expert" they can continue to be big internet experts. This is a kind of death though --- if they aren't learning anything, how is that different from being dead? --- ANS-Forth cult members are like zombies that continue marching forward into the future despite being brain-dead.

Julian Fondren

unread,
Apr 21, 2017, 3:12:13 AM4/21/17
to
On Friday, April 21, 2017 at 12:02:53 AM UTC-5, hughag...@gmail.com
> I'm always willing to learn new concepts, and become a better programmer.

What you aren't willing to do is learn Forth concepts, and become a
better Forth programmer. Because you think you know all that stuff
already, and don't like it. So you're always saying things like

> You can't just modify strings willy-nilly.

or:

> It is a mistake to force the user to remember which strings can be
> modified, which can not be modified (because they came from S" or
> S\") and which will likely get overwritten

And when you wax on about how things should be, you spend half the
time imposing new restrictions on implementors and programmers, and
removing flexibility that you don't care about.

You're utterly aghast at 'global variables', anyone ever writing
something that's not reentrant, anyone ever writing something that
doesn't work with local variables. When someone proposes that you keep
the entirety of a program in mind, you think this is just absurd. Your
most consistent perspective is that of a programmer who knows nothing
about Forth. What would cause such a person to sneer in derision at
you, Hugh Aguilar, the world's only professional Forth programmer?
Anything like that must be stamped out! Anything like that is an
embarrassment to Forth!

It's "too hard" to remember the properties of strings in a program, so
just use this tool that will manage your memory for you. Some of its
operations are fast and work in fixed memory; some of them (the same
exact operations, applied to different kinds of strings) will copy a
bunch of data for you behind your back. It's auto-magic!

LEARN

RUST

https://www.rust-lang.org/en-US/

Rudy Velthuis

unread,
Apr 21, 2017, 5:47:19 AM4/21/17
to
Paul Rubin wrote:

> "Rudy Velthuis" <newsg...@rvelthuis.de> writes:
> > Then I don't quite understand it. If you already have a mathematical
> > real, then what is the problem?
>
> You want to find a rational approximation to your mathematical real.
> E.g. suppose your real is pi.

Oh, Ok, now I get it.
--
Rudy Velthuis http://www.rvelthuis.de

"Asswhole = a complete ass" -- John McTaggart in bpot

Rudy Velthuis

unread,
Apr 21, 2017, 5:52:03 AM4/21/17
to
krishna...@ccreweb.org wrote:

> Your unwarranted and personal rants against Elizabeth Rather
> completely discredit any positive contributions you make to
> discussion topics in this newsgroup.

Fully agreed.



--
Rudy Velthuis http://www.rvelthuis.de

"I am become death, shatterer of worlds."
-- Robert J. Oppenheimer (1904-1967) (citing from the
Bhagavad Gita, after witnessing the world's first nuclear
explosion)

Rudy Velthuis

unread,
Apr 21, 2017, 5:55:30 AM4/21/17
to
hughag...@gmail.com wrote:

> On Thursday, April 20, 2017 at 4:22:30 PM UTC-7,
> krishna...@ccreweb.org wrote:
> > On Thursday, April 20, 2017 at 5:49:53 PM UTC-5,
> > hughag...@gmail.com wrote:
> >
> > > One of the many blunders of ANS-Forth was to make locals with
> > > with TO --- it would have been much better to make the local
> > > provide an address and then use @ and ! on that address --- if
> > > the local is big enough to contain a double or a float, then D@
> > > and D! as well as F@ and F! can also be used on the local's
> > > address. ....
> > [crap clipped]
> >
> > Your unwarranted and personal rants against Elizabeth Rather
> > completely discredit any positive contributions you make to
> > discussion topics in this newsgroup.
> >
> > Goodbye.
>
> Goodbye to you --- brown-noser!

That's gross too.

And I agree with Krishna.

You can, of course, call me a brown-noser too, but I have absolutely no
affiliation or reason to brown-nose anyone here, so you would be pretty
wrong.

Such (unnecessary) rants, against a single person, reduce your
credibility to almost zero. You could have easily brought your
arguments across without them.

--
Rudy Velthuis http://www.rvelthuis.de

"Kindness is a mark of faith, and whoever has not kindness has
not faith."
-- Prophet Muhammad

The Beez

unread,
Apr 21, 2017, 6:18:34 AM4/21/17
to
On Friday, April 21, 2017 at 3:49:51 AM UTC+2, krishna...@ccreweb.org wrote:
> I've not implemented locals in kForth, nor do I feel any compulsion to do so.
>
> Krishna

I feel with you. I have a kind of crude "bolt-on" libraries for 4tH, which I mainly (exclusively?) use for porting purposes. Sure, I could do locals in native 4tH, but then I'd increase the function call overhead for everything and everyone - turning it into some kind of C.

I learned from the old FIG editor that one could use R@ as some kind of local constant - and that helped me a lot through the years. When 3.63.0 comes out I will increase that to the first three items on the return stack, r@, r'@ and r"@. That will IMHO even lessen the need for locals since you can park loop limits, pointers and other constants there, freeing up space on the data stack.

Note the added advantage is that they are "random access" - no stack juggling.

Sure, you can do that in 4tH right now, but either "illegally" or with some serious overhead.

Hans Bezemer

lehs

unread,
Apr 21, 2017, 8:35:37 AM4/21/17
to
Den fredag 21 april 2017 kl. 01:22:30 UTC+2 skrev krishna...@ccreweb.org:
> ...
> Your unwarranted and personal rants against Elizabeth Rather completely discredit any positive contributions you make to discussion topics in this newsgroup.
>
> Goodbye.

I agree. Unlike Hugh Aguilar Elizabeth Rather Conklin is a likable asset here. She always answer kindly and interesting.

Hugh is totally fixed with the excellence of his own code and culturing conspiracy in Forth community. I'm no psychiatrist but from introspection and Wikipedia I guess on diseases as paranoia, megalomania and Tourettes syndrome. Maybe all of them.

Goodbye for me too.

krishna...@ccreweb.org

unread,
Apr 21, 2017, 9:39:48 PM4/21/17
to
On Friday, April 21, 2017 at 5:18:34 AM UTC-5, The Beez wrote:
> On Friday, April 21, 2017 at 3:49:51 AM UTC+2, krishna...@ccreweb.org wrote:
> > I've not implemented locals in kForth, nor do I feel any compulsion to do so.
> >
> > Krishna
>
> I feel with you. I have a kind of crude "bolt-on" libraries for 4tH, which I mainly (exclusively?) use for porting purposes. Sure, I could do locals in native 4tH, but then I'd increase the function call overhead for everything and everyone - turning it into some kind of C.
>

Yes, while I appreciate the language, "C", I have no desire to use Forth as a reverse notation, syntax-free, C-like language. I'm glad that someone went to the trouble of putting in a Forth entry into Rosetta code for the rational approximation problem. However, I am critical (in the positive sense of the word) of the use of locals in this example. Take, for example, the following code:
...
thereal F- FABS to temperror

temperror besterror F< IF
temperror to besterror I to numtor J to denom
THEN
...

The local, "temperror", is frivolous, because it is used nowhere else in the code and the fp value is available on the stack, to be used as follows
...
thereal F- FABS
FDUP besterror F< IF besterror F! ... ELSE FDROP THEN
...

Similarly, with the local, "thereal". It's simple enough without obfuscating the code to leave it on the stack. Anyway, I didn't want to make this a thread about the dangers of locals, but I guess I started it.


> I learned from the old FIG editor that one could use R@ as some kind of local constant - and that helped me a lot through the years. When 3.63.0 comes out I will increase that to the first three items on the return stack, r@, r'@ and r"@. That will IMHO even lessen the need for locals since you can park loop limits, pointers and other constants there, freeing up space on the data stack.
>
> Note the added advantage is that they are "random access" - no stack juggling.

True, but you've got to be careful to pop them, and especially be careful inside a loop.


Krishna


hughag...@gmail.com

unread,
Apr 21, 2017, 9:43:30 PM4/21/17
to
One of the many blunders of Elizabeth Rather is in section 3.2.3.2:
-------------------------------------------------------------------
The control-flow stack may, but need not, physically exist in an
implementation. If it does exist, it may be, but need not be, implemented
using the data stack. The format of the control-flow stack is
implementation defined. Since the control-flow stack may be implemented
using the data stack, items placed on the data stack are unavailable to a
program after items are placed on the control-flow stack and remain
unavailable until the control-flow stack items are removed.
-------------------------------------------------------------------

What happened here is that some of the ANS-Forth committee members wanted the control-flow stack to be distinct from the data-stack because this is obviously a good idea. Forth Inc. uses the data-stack for control-flow data however (Elizabeth Rather has described this as being "convenient"). So, the solution as always, was ambiguity. She just said that either behavior would be standard. As a practical matter, what this means is that Forth Inc.'s idiotic method becomes the standard. Everybody has to assume that the control-flow stack is the data-stack, because otherwise their code won't work under SwiftForth and they will get blamed for writing a non-standard program.

When meta-compiling, it is necessary to put your data somewhere. The obvious place would be the data-stack. This can't be done however, because the control-flow data (generated by IF BEGIN etc.) is on the data-stack getting in the way of you accessing your own data. So, you need to put your data somewhere else. The two choices are the return-stack and locals. The return-stack can be used (Bernd Paysan has posted code on comp.lang.forth that uses the return-stack), but this only works when you have very little data. Locals work a lot better.

Here is an example:
----------------------------------------------------------------------------

true value bounds-check?

\ Use TO to set BOUNDS-CHECK? to FALSE when you are ready for your production version.

: check1 ( x1 dim1 -- x1 ) over u> not abort" *** array index 1 out of bounds ***" ;
: check2 ( x2 dim2 -- x2 ) over u> not abort" *** array index 2 out of bounds ***" ;
: check3 ( x3 dim3 -- x3 ) over u> not abort" *** array index 3 out of bounds ***" ;
: check4 ( x4 dim4 -- x4 ) over u> not abort" *** array index 4 out of bounds ***" ;
: check5 ( x5 dim4 -- x5 ) over u> not abort" *** array index 5 out of bounds ***" ;
: check6 ( x6 dim4 -- x6 ) over u> not abort" *** array index 6 out of bounds ***" ;

: <check1> ( dim1 -- ) bounds-check? if lit, postpone check1 else drop then ;
: <check2> ( dim2 -- ) bounds-check? if lit, postpone check2 else drop then ;
: <check3> ( dim3 -- ) bounds-check? if lit, postpone check3 else drop then ;
: <check4> ( dim4 -- ) bounds-check? if lit, postpone check4 else drop then ;
: <check5> ( dim4 -- ) bounds-check? if lit, postpone check5 else drop then ;
: <check6> ( dim4 -- ) bounds-check? if lit, postpone check6 else drop then ;

: <3array> { dim1 dim2 dim3 siz1 name | adr siz siz2 siz3 -- } \ 3-dimensional array
dim1 siz1 * to siz2 dim2 siz2 * to siz3 dim3 siz3 * to siz
align here to adr siz allot
name get-current :name \ runtime: x1 x2 x3 -- element-adr
dim3 <check3>
siz3 lit*, swap, \ runtime: x1 x3*s3 x2
dim2 <check2>
siz2 lit*, +, swap, \ runtime: x3*s3+x2*s2 x1
dim1 <check1>
siz1 lit*, +, adr lit+, ;, \ runtime: x3*s3+x2*s2+x1*s1+adr
c" ^" name get-current :2name \ runtime: -- adr
adr lit, ;,
c" lim-" name get-current :2name \ runtime: -- adr-past
adr siz + lit, ;,
name c" -zero" get-current :2name \ runtime: --
adr lit, siz lit, s" erase ; " evaluate
name c" -size" get-current :2name \ runtime: -- siz1
siz1 lit, ;,
name c" -dim" get-current :2name \ runtime: -- dim1 dim2 dim3
dim1 lit, dim2 lit, dim3 lit, ;,
;

: 3array ( dim1 dim2 dim3 size -- ) bl word hstr dup >r <3array> r> dealloc ;

----------------------------------------------------------------------------

You said:
"I've not implemented locals in kForth, nor do I feel any compulsion to do so."
This tells me that you have never written any meta-compiling words. How else do you work around Elizabeth Rather's idiotic rule that control-flow data may be on the data-stack getting in your way?

krishna...@ccreweb.org

unread,
Apr 21, 2017, 9:46:24 PM4/21/17
to
On Friday, April 21, 2017 at 8:39:48 PM UTC-5, krishna...@ccreweb.org wrote:
...
> thereal F- FABS
> FDUP besterror F< IF besterror F! ... ELSE FDROP
...

Oops. That should have been,

...
thereal F- FABS
FDUP besterror F@ F< IF besterror F! ... ELSE FDROP THEN
...

The local "besterror" should have been an fvariable, in case we needed to do a post-mortem on it.

Krishna

hughag...@gmail.com

unread,
Apr 21, 2017, 10:05:20 PM4/21/17
to
On Friday, April 21, 2017 at 5:35:37 AM UTC-7, lehs wrote:
> Den fredag 21 april 2017 kl. 01:22:30 UTC+2 skrev krishna...@ccreweb.org:
> > ...
> > Your unwarranted and personal rants against Elizabeth Rather completely discredit any positive contributions you make to discussion topics in this newsgroup.
> >
> > Goodbye.
>
> I agree. Unlike Hugh Aguilar Elizabeth Rather Conklin is a likable asset here. She always answer kindly and interesting.

The subject of continued fractions has been discussed here before:
https://groups.google.com/forum/#!topic/comp.lang.forth/BcWvGxFFuzA%5B1-25%5D

I was trying to port the CF program of Nathaniel Grossman to ANS-Forth and I was frustrated that there was no double-precision division in ANS-Forth. Way back in 1984 Grossman had to write UD/MOD in high-level Forth because Elizabeth Rather had failed to provide it in Forth-83. Then when ANS-Forth came out, Elizabeth Rather failed to provide it again.

This was my first-ever contact with Elizabeth Rather:

On Friday, November 20, 2009 at 12:07:12 AM UTC-7, Elizabeth D Rather wrote:
> Hugh Aguilar wrote:
> ...
> > The problem is the ANS-Forth standard. Really, how obvious was the
> > need for double-precision arithmetic? This could have been an
> > extension to the language similar to floating-point. Compiler-writers
> > working on small microprocessors could decline to implement it if they
> > didn't want to.
> >
> > I am frustrated with the ANS-Forth standard because I believe that the
> > bad design of the standard is the #1 reason for the failure of Forth
> > to become an important language. Forth was doing pretty well in the
> > 1980s, but we needed a standard. What we got was Forth-83, and then
> > ANS-Forth-94, both of which were badly designed. With some more
> > thoughtful leadership we could have succeeded.
>
> There are D+, D-, M*, M/, and M*/ (and the unsigned operators). These
> were adequate in a very wide variety of projects over a 30 year period,
> many of which were extremely computation-intensive and running on slow
> 16-bit processors.
>
> Forth's design is pragmatic: it has functions that have been needed and
> that have proven their usefulness *in Forth*, not necessarily those that
> have been required in other languages. Generally speaking, Forth has
> the most flexible set of *integer* arithmetic operators of any language.
> In particular, M*/ was one of Chuck's most brilliant innovations. I'm
> sure if Chuck were trying to do your continued fractions that is what he
> would rely on. Yes, that sometimes requires thinking differently, like
> many other things in Forth.
>
> Cheers,
> Elizabeth

My interpretation of this post is that she is telling me that I can never be an ANS-Forth programmer. She is playing her trump card, which is that she learned Forth directly from Charles Moore in the 1970s and hence knows everything there is to know about Forth, and this give her alone the right to define what Forth is. How can I beat the trump card? I have never met Charles Moore, and I didn't learn Forth until 1984. With her trump card, she can beat me every day, and no Forth code that I write can ever have any value.

Paul Rubin is well aware that ANS-Forth lacks double-precision division, which is why he wrote his continued-fraction program in Haskell. This qualifies him to be an ANS-Forth programmer! By comparison, I can't be an ANS-Forth programmer because my continued-fraction program is written in ANS-Forth --- this disqualifies me from being an ANS-Forth programmer because my program shines a spotlight on the failure of ANS-Forth to provide double-precision arithmetic --- a loyal cult member never mentions the many failings of ANS-Forth, but will instead write their code in Haskell or whatever, while continuing to declare that ANS-Forth is a viable language.

All of this talk about "thinking differently" implies that ANS-Forth is a cult. All cults declare themselves to be the standard, and everybody else in the world to be non-standard wanna-bees. All cults require their members to "think differently" --- that is: differently from reality --- the cult is founded entirely upon fantasy, so reality is what they hate and fear the most.

> Hugh is totally fixed with the excellence of his own code and culturing conspiracy in Forth community. I'm no psychiatrist but from introspection and Wikipedia I guess on diseases as paranoia, megalomania and Tourettes syndrome. Maybe all of them.

All cults' arguments eventually (and usually quickly) devolve into calling everybody else in the world insane. This is the hallmark of cult behavior.

> Goodbye for me too.

What have you ever written in Forth other than your big-number package?

I don't need you.

Paul Rubin

unread,
Apr 22, 2017, 12:56:01 AM4/22/17
to
>> increase that to the first three items on the return stack, r@, r'@
>> and r"@. ...
> True, but you've got to be careful to pop them, and especially be
> careful inside a loop.

Is this really much different from using PICK on the data stack?

Also it seems like just a small step from that to having a frame pointer
that you can index from, that gets set to the top of the return stack
(TOR) when entering a word, and then TOR is set to it on returning.

Jan Coombs

unread,
Apr 22, 2017, 5:28:23 AM4/22/17
to
I've just noticed that my style pattern for reading c.l.f has
evolved into this:

On Fri, 21 Apr 2017 18:43:29 -0700 (PDT)
[someone] wrote:

> On Thursday, April 20, 2017 at 6:49:51 PM UTC-7,
> [someone previously] wrote:

[skip quoted context to save time, getting slightly irritated if
I've already read it twice before and is not directly relevant to
current post]

> One of the many blunders of [persons name]

[Detect personal attack and skip remainder of post. Make mental
note to skip next handful of posts from same poster to preserve
my generally optimistic state of mind.]

It's like a war of attrition, will we be able to adapt
sufficiently to survive?

Jan Coombs

Mark Wills

unread,
Apr 22, 2017, 5:33:37 AM4/22/17
to
It's one of the reasons that I don't stop by CLF much these days.

krishna...@ccreweb.org

unread,
Apr 22, 2017, 11:33:44 AM4/22/17
to
On Friday, April 21, 2017 at 11:56:01 PM UTC-5, Paul Rubin wrote:
> >> increase that to the first three items on the return stack, r@, r'@
> >> and r"@. ...
> > True, but you've got to be careful to pop them, and especially be
> > careful inside a loop.
>
> Is this really much different from using PICK on the data stack?
>

RPICK ?

That doesn't look right.

KM

Paul Rubin

unread,
Apr 22, 2017, 4:35:13 PM4/22/17
to
krishna...@ccreweb.org writes:
>> Is this really much different from using PICK on the data stack?
> RPICK ? That doesn't look right.

RPICK exists in many implementations but I meant regular PICK.

minf...@arcor.de

unread,
Apr 23, 2017, 5:28:40 AM4/23/17
to
Am Freitag, 21. April 2017 12:18:34 UTC+2 schrieb The Beez:

> I learned from the old FIG editor that one could use R@ as some kind of local constant - and that helped me a lot through the years. When 3.63.0 comes out I will increase that to the first three items on the return stack, r@, r'@ and r"@.

Been there, done that, left, because it's ugly and still limited IMO.
Because: When do programmers like locals? When they have _many_ parameters to a function, not just three.

The more general solution is to introduce a stack frame for words with locals. At compile-time you can use colon-sys (modified by locals|) to signal to ; (semis) that it shall compile a frame-cleaning next/return instead of a normal one.

Yes, stackframes smell of C, but it is a clean and simple way, not altoo difficult to implement, and with practically no runtime costs.

The Beez

unread,
Apr 24, 2017, 3:58:33 AM4/24/17
to
On Saturday, April 22, 2017 at 3:39:48 AM UTC+2, krishna...@ccreweb.org wrote:
> Yes, while I appreciate the language, "C", I have no desire to use Forth as a reverse notation, syntax-free, C-like language.

Likewise ;-) 4tH is written in C. A few years ago I had to add a "gcc" like executable and I was surprised how little fun that was. Adding a few snippets to enhance an existing program isn't too "disturbing", however writing an entire program is nowadays.

> I'm glad that someone went to the trouble of putting in a Forth entry into Rosetta code for the rational approximation problem. However, I am critical (in the positive sense of the word) of the use of locals in this example. Take, for example, the following code <snip>

That's exactly the point: locals invite easy solutions that aren't very "Forth-like" anymore. I've added a lot of "local free" code to Rosetta.

> > Note the added advantage is that they are "random access" - no stack juggling.
> True, but you've got to be careful to pop them, and especially be careful inside a loop.

I wouldn't do it in a DO..LOOP for obvious reasons, however BEGIN..REPEAT is pretty painless as long as you put stuff up there which value doesn't change during execution, e.g. array offsets, loop limits, etc. Note the entire advantage disappears when you have to update a three-item deep return stack item. And at the end of the loop you simple move 'em off and drop 'em.

Hans Bezemer


minf...@arcor.de

unread,
Apr 24, 2017, 4:08:05 AM4/24/17
to
Yes, counted loops are slower because they are counting. ;-) But honestly, I have not encountered big delays so far. But perhaps it is because I do address the return stack like any other array in memory. Since my locals live also in the return stack, locals access time is pretty fast too.

The Beez

unread,
Apr 24, 2017, 4:14:47 AM4/24/17
to
Although Hugh's rude comments and ad hominem attacks would warrant immediate deletion on any of my blogs and my high respect for Elizabeth D Rather goes without saying, I have to agree with Hugh on this one:

> > The problem is the ANS-Forth standard. Really, how obvious was the
> > need for double-precision arithmetic? This could have been an
> > extension to the language similar to floating-point. Compiler-writers
> > working on small microprocessors could decline to implement it if they
> > didn't want to.

When I designed 4tH that was exactly a point I wanted to fix: a Forth without double words. Hence, <#, #, #> work on single cell numbers and S>D and D>S do nothing to allow for easy porting.

Yes, nowadays 4tH has got the whole shebang, but as a LOADABLE library - just like floating point. The inclusion of a few mixed and double words in the core is half hearted and IMHO the language would win some consistency if that stuff was moved completely to a separate library.

Sure, it would break some code - but that's how it is when you fix errors of the past. During the development of 4tH I broke code several times - and I'm happy today that I did. Note lots of languages (Perl, Python) break lots of code in order to get better and better.

Hans Bezemer

Cecil Bayona

unread,
Apr 24, 2017, 12:31:44 PM4/24/17
to
What is your procedure to test and develop 4th code?

--
Cecil - k5nwa

hughag...@gmail.com

unread,
Apr 24, 2017, 2:43:32 PM4/24/17
to
On Monday, April 24, 2017 at 1:14:47 AM UTC-7, The Beez wrote:
> Although Hugh's rude comments and ad hominem attacks would warrant immediate deletion on any of my blogs and my high respect for Elizabeth D Rather goes without saying, I have to agree with Hugh on this one:
>
> > > The problem is the ANS-Forth standard. Really, how obvious was the
> > > need for double-precision arithmetic? This could have been an
> > > extension to the language similar to floating-point. Compiler-writers
> > > working on small microprocessors could decline to implement it if they
> > > didn't want to.

Everybody wants to be an expert on ethics! I'm unimpressed by Beez and his self-proclaimed status as an expert on ethics.

Where are the big ANS-Forth ethics experts on when ad hominem attacks are made against me? John Passaniti, Alex McDonald, Rick Collins and Julien Fondren all do this routinely. Apparently the ANS-Forth ethics experts are too busy brown-nosing Elizabeth Rather to notice --- their silence is deafening!

Consider this thread:
https://groups.google.com/forum/#!topic/comp.lang.forth/ohE8mx7tWQU%5B1-25%5D
Here my name is listed as a supporter (or contributor, or participant, or whatever) of the Paysan-faked quotations. This is the second time this has happened. I threatened a libel lawsuit previously to make them stop, but here they are doing it again, so I have to threaten a libel lawsuit again. Alex McDonald claims that my complaint about them putting my name in the RfD as a supporter against my wishes is "piggy squealing" and that the Forth-200x committee has the right to do this. Piggy squealing??? That sounds like an ad hominem attack to me. The ANS-Forth ethics experts are silent because they want Fort-200x to appear to have the support of every piggy in the entire Forth community, including myself.

Julien Fondren has made death threats against myself and Darin Murphy, but the ANS-Forth ethics experts are silent because Julien Fondren brown-noses Elizabeth Rather and hence is given free rein to attack anybody who threatens Forth Inc. --- apparently he believed that Darin had the potential to eventually compete against Forth Inc., because he was writing actual code rather than just proclaiming himself to be an expert without writing any code as is usual on comp.lang.forth.

Consider this thread:
https://groups.google.com/forum/#!topic/comp.lang.forth/Mfi54CwQVCo
Here Juergen Pintaske threatens to find Gavino's employer and family (his granny!) and harass them. The ANS-Forth ethics experts are silent because Juergen Pintaske is an employee of Stephen Pelc and hence is given free rein to attack anybody who threatens MPE --- how Gavino represents a threat to MPE is unclear though; he's just a galoot with a two-minute attention-span.

Consider this thread:
https://groups.google.com/forum/#!topic/comp.lang.forth/D_w4krw4B0s
Here Alex McDonald clearly states that writing ANS-Forth doesn't make me an ANS-Forth programmer, or even a programmer at all. He himself is a mighty great ANS-Forth programmer though, because he brown-noses Elizabeth Rather. This, of course, bolsters my claim that ANS-Forth is a cult.

On Sunday, April 23, 2017 at 1:16:07 AM UTC-7, Alex wrote:
> On 4/23/2017 04:54, Ron Aaron wrote:
> >
> >
> > On 23/04/2017 1:01, hughag...@gmail.com wrote:
> >
> >> My point is that if you want speed, then you need to write in assembly-language
> >
> > Incorrect.
> >
> > A poorly-written ASM program will not out-perform a well-written (choose
> > your language) program.
> >
> > A great ASM program using a poor algorithm will not out-perform (for
> > long) a poorly written HLL program using an excellent algorithm.
> >
> > A complex program in ASM may take many (many!) times longer to write
> > than an equivalent HLL program. So even if theoretically the ASM
> > program would run faster, your customer will long since have fired you
> > for lack of delivery.
> >
> > There is more than one variable to consider.
>
> Yes. In particular, there is a tendency for some to write & post code,
> and demand that others do so, without too much consideration to design,
> maintenance, applicability etc.
>
> Our resident Ruby/Scheme/Python obsessive is a case in point.
> WJ/waxman/Robert L or whatever handle he's using this week is a
> minimalist; he finds an esoteric problem, a library to call, and writes
> some fantastically arcane incantation in a single line so he can declare
> victory. "In Forth?" being his signature flourish.
>
> Hugh is at the opposite end of the spectrum; volume and yardage counts
> here. Piles of code, endlessly repeated, A sneering "In Forth?" is
> replaced by novel's worth of hollering and shouting at everyone that
> they're sales clowns because they're not advanced programmers liek wot
> he is coz novice code innit.
>
> Neither is a programmer, but neither can see it.
>
> --
> Alex

The Beez

unread,
Apr 25, 2017, 3:35:18 AM4/25/17
to
On Monday, April 24, 2017 at 8:43:32 PM UTC+2, hughag...@gmail.com wrote:
Ok, You totally ignored my diplomatic attempt to agree with the issue you posed without agreeing with your rant and steer the discussion back to your bruised ego. I know rants. I can give you a few when I started 4tH back in 1994. Brush it off, man!

You're not interested in my bruised ego and I'm certainly not interested in yours. And that's OK. Whatever I may think of you as a person, there is a little bit of Hugh code in 4tH and that benefits my users.

If I can increase that amount of code I'm happy to let you beat me up every day.

Hans Bezemer

The Beez

unread,
Apr 25, 2017, 3:52:57 AM4/25/17
to
On Monday, April 24, 2017 at 6:31:44 PM UTC+2, Cecil - k5nwa wrote:
> What is your procedure to test and develop 4th code?
- First, write or port code;
- Second, get it to compile - return to 1 if it fails;
- Third, get it to run - if it performs flawless, goto 6;
- 4tH, try to pinpoint the error (decompile);
- Fifth, strategically place .S markers, go to 3;
- Sixth, decompile again and see if it can be optimized, goto 2;
- Seventh, place it SVN;
- Eighth, "desktop debug" it, a lost art IMHO, goto 1 if required;
- Nineth, goto 1.

I use KDE Kate 99% of the time, since I have easy access to the prompt there.

Hans Bezemer

The Beez

unread,
Apr 25, 2017, 4:09:37 AM4/25/17
to
On Monday, April 24, 2017 at 8:43:32 PM UTC+2, hughag...@gmail.com wrote:
> Here Alex McDonald clearly states that writing ANS-Forth doesn't make me an ANS-Forth programmer, or even a programmer at all. He himself is a mighty great ANS-Forth programmer though, because he brown-noses Elizabeth Rather. This, of course, bolsters my claim that ANS-Forth is a cult.

Only 16 year old girls are interested in other peoples opinions. I still post code here, knowing some of the self proclaimed experts here will burn it without considering the design objectives. I, for one, don't care stack acrobatics in library code - nor the length of some words if I can't get some significant factoring advantages (less opcodes) or structure that allows enhancement.

https://sourceforge.net/p/forth-4th/code/HEAD/tree/trunk/4th.src/lib/tabs.4th

On the other hand, they don't know what I think of their code. And yes, there are times I can only gasp at the beautiful and elegant code some people design sometimes.

A bit of pragmatism isn't too bad every now and then. And that also goes for ANS Forth. Yes, a certain compatibility with ANS Forth isn't bad. You can get your hands on a lot more code and it makes it much easier to port it. Wil Baden convinced me of that when I still used Forth-79 for 4tH back in the last century.

There is a lot of ANS code I ported and a lot of 4tH code I ported back - with much more ease. And yes, there are still Forth-79 features in 4tH, like the value of TRUE, -1 +LOOP, etc. That's the thing if you write your own compiler. You can make that choices. It's a lot more fruitful than banging your head against the wall IMHO.

Hans Bezemer

hughag...@gmail.com

unread,
Apr 25, 2017, 1:52:11 PM4/25/17
to
This is what Elizabeth Rather says about herself:
-------------------------------------------------
Elizabeth Rather is the co-founder of FORTH, Inc. and is a leading expert in the Forth programming language. Elizabeth was a colleague of Chuck Moore when he worked at NRAO in the early 1970s. During his development of Forth, she became the second ever Forth programmer. Since then, she has become a leading expert in the language and one of its main proponents. Elizabeth was the chair of the ANSI Technical Committee that produced the ANSI Standard for Forth (1994). She is an author of several books on Forth and gave many training seminars on its usage.
-------------------------------------------------

What part of the term "leading expert" do you not understand? The meaning of this term is that all Forth programmers are required to brown-nose her. There is no other interpretation of her use of this offensive term.

If you are polite to her after she insults you in such a gross manner, then you are a brown-noser. Your meek acceptance of the this blatant insult completely discredits any positive contributions you make to discussion topics in this newsgroup --- it is obvious that you don't have a shred of self-respect --- this is very comparable to accepting the nickname "puto" because you want to be accepted by the in-crowd, and your motto in life is: "Go along to get along."

minf...@arcor.de

unread,
Apr 26, 2017, 4:55:45 AM4/26/17
to
Am Dienstag, 25. April 2017 10:09:37 UTC+2 schrieb The Beez:
> On the other hand, they don't know what I think of their code. And yes, there are times I can only gasp at the beautiful and elegant code some people design sometimes.

Well spoken. It's these rare intellectually inspiring gems that keeps software analysis interesting (otherwise it can be very boring). And sometimes one is also allowed to be proud of one's own creations.

Even if it's only a small Forth compiler. ;-)

Rudy Velthuis

unread,
Apr 28, 2017, 11:16:12 PM4/28/17
to
hughag...@gmail.com wrote:

> This is what Elizabeth Rather says about herself:

<yawn>

You seem to have a chip on your shoulder. Get over it.


--
Rudy Velthuis http://www.rvelthuis.de

"Descended from the apes? Let us hope that it is not true. But
if it is, let us pray that it may not become generally known."
-- FA Montagu.
0 new messages