I just gave this a go, and here's what I have so far based on the Wikipedia link Claude gave. Send the decimal through the left inlet, and it outputs the numerator and denominator as a list. The argument is the maximum value the denominator is allowed to be, which keeps it from going crazy trying to figure out irrational numbers and also seems to make up for some floating-points errors. You can change the max with the right inlet as well. Right now it defaults to 100, but that may be too low. Higher values=more accurate, but potentially more computation.
I haven't implemented the rules for decrementing the last value of the continuous fractions, so it's not perfect. But it does give 355/113 for pi. :-)
.mmb
On Fri, Dec 16, 2011 at 2:46 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
From: i go bananas hard.off@gmail.com To: Ludwig Maes ludwig.maes@gmail.com Cc: pd-list@iem.at Sent: Friday, December 16, 2011 1:16 PM Subject: Re: [PD] number to fractions external?
if you had read the thread, you would have seen that claude posted a link to that technique.
now go and make a PD patch that does it, mr smart guy.
Wow, how much cpu does that take in Python? I tried this approach in the form
of an abstraction, with a nested until, and worst case it can take as much as a quarter of
a second to compute with the constants provided below.
(Pentium Dual-core 2.6gHz in WinXP with 0.43 nightly build)
-Jonathan
On Sat, Dec 17, 2011 at 3:00 AM, Ludwig Maes ludwig.maes@gmail.com wrote:
If you guys 'd done your math, you'd know there is an ancient algorithm for approximating numbers by fractions and its called continued fractions.
On 16 December 2011 18:38, Lorenzo Sutton lorenzofsutton@gmail.com wrote:
On 16/12/11 16:05, Alexandre Torres Porres wrote:
looks like a job for an external
Not really answering the OP question but something could be done in Python:
def find_frac(num): f = float(num) last_error = 1000 best = (0,0) for i in xrange(1,1001): for j in xrange(1,i+1): divide = (float(i) / float (j)) if divide == f: return ((i,j),0) err = abs(divide - f) if err < last_error: best = (i,j) last_error = err return (best,last_error)
This would try to find the exact fraction or the one with the smallest error (trying up to 1000/1000). It would return (numerator, denominator, error). Guess it would work well at least up to 100 but only for positive numbers... and... not for numbers < 1.. and surely it's not optimised etc. etc. :)
> find_frac(2)
((2, 1), 0)
> find_frac(1.5)
((3, 2), 0)
> find_frac(1.333333333333333333333333333)
((4, 3), 0)
> find_frac(2.4)
((12, 5), 0)
> find_frac(2.8)
((14, 5), 0)
> find_frac(2.987654321)
((242, 81), 1.234568003383174e-11)
> find_frac(50.32)
((956, 19), 0.004210526315787888)
> find_frac(50.322)
((956, 19), 0.006210526315790332)
> find_frac(50.4)
((252, 5), 0)
> find_frac(10.33)
((971, 94), 0.00021276595744623705)
> find_frac(10.33333333333333333333333333)
((31, 3), 0)
Lorenzo.
2011/12/16 i go bananas <hard.off@gmail.com mailto:hard.off@gmail.com>
actually, i'm not going to do anything more on this.
i had a look at the articles claude posted, and they went a bit far over my head.
my patch will still work for basic things like 1/4 and 7/8, but i wouldn't depend on it working for a serious application. As you first suggested, it's not so simple, and if you read claude's articles, you will see that it isn't.
it's not brain science though, so maybe someone with a bit more number understanding can tackle it.
On Sat, Dec 17, 2011 at 12:51 AM, Alexandre Torres Porres
<porres@gmail.com mailto:porres@gmail.com> wrote:
> i had a go at it
thanks, I kinda had to go too, but no time... :(
> yeah, my patch only works for rational numbers.
you know what, I think I asked this before on this list,
deja'vu
> will have a look at the article / method you posted, claude.
are you going at it too? :)
by the way, I meant something like 1.75 becomes 7/4 and not 3/4, but that is easy to adapt on your patch
thanks
cheers
2011/12/16 i go bananas <hard.off@gmail.com
by the way, here is the method i used:
first, convert the decimal part to a fraction in the form of n/100000 next, find the highest common factor of n and 100000 (using the 'division method' like this: http://easycalculation.com/what-is-hcf.php )
then just divide n and 100000 by that factor.
actually, that means it's accurate to 6 decimal places, i guess. well...whatever :D
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list