rational_approximations.pl 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 16 January 2019
  4. # https://github.com/trizen
  5. # Simple and efficient algorithm for finding the first continued-fraction convergents to a given real constant.
  6. # Continued-fraction convergents for PI:
  7. # https://oeis.org/A002485
  8. # https://oeis.org/A002486
  9. # See also:
  10. # https://en.wikipedia.org/wiki/Continued_fraction
  11. use 5.020;
  12. use strict;
  13. use warnings;
  14. use experimental qw(signatures);
  15. use Math::AnyNum qw(:overload float);
  16. sub rational_approximations ($x, $callback, $first = 10) {
  17. $x = float($x) || return;
  18. my ($n1, $n2) = (0, 1);
  19. my ($d1, $d2) = (1, 0);
  20. my $f = $x;
  21. for (1 .. $first) {
  22. my $z = int($f);
  23. $n1 += $n2 * $z;
  24. $d1 += $d2 * $z;
  25. ($n1, $n2) = ($n2, $n1);
  26. ($d1, $d2) = ($d2, $d1);
  27. $callback->($n2 / $d2);
  28. $f -= $z;
  29. $f || last;
  30. $f = 1 / $f;
  31. }
  32. }
  33. my $x = atan2(0, -1);
  34. my $f = sub ($q) { say "PI =~ $q" };
  35. rational_approximations($x, $f, 20);
  36. __END__
  37. PI =~ 3
  38. PI =~ 22/7
  39. PI =~ 333/106
  40. PI =~ 355/113
  41. PI =~ 103993/33102
  42. PI =~ 104348/33215
  43. PI =~ 208341/66317
  44. PI =~ 312689/99532
  45. PI =~ 833719/265381
  46. PI =~ 1146408/364913
  47. PI =~ 4272943/1360120
  48. PI =~ 5419351/1725033
  49. PI =~ 80143857/25510582
  50. PI =~ 165707065/52746197
  51. PI =~ 245850922/78256779
  52. PI =~ 411557987/131002976
  53. PI =~ 1068966896/340262731
  54. PI =~ 2549491779/811528438
  55. PI =~ 6167950454/1963319607
  56. PI =~ 14885392687/4738167652