Mercurial > libavcodec.hg
comparison utils.c @ 1549:5e643dd7e889 libavcodec
use continued fractions to approximate a fraction if its numerator or denominator is too large
| author | michael |
|---|---|
| date | Mon, 20 Oct 2003 22:33:53 +0000 |
| parents | dd544554ed42 |
| children | ece0ad14a35d |
comparison
equal
deleted
inserted
replaced
| 1548:dd544554ed42 | 1549:5e643dd7e889 |
|---|---|
| 682 } | 682 } |
| 683 } | 683 } |
| 684 | 684 |
| 685 int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ | 685 int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ |
| 686 int exact=1, sign=0; | 686 int exact=1, sign=0; |
| 687 int64_t gcd, larger; | 687 int64_t gcd; |
| 688 | 688 |
| 689 assert(den != 0); | 689 assert(den != 0); |
| 690 | 690 |
| 691 if(den < 0){ | 691 if(den < 0){ |
| 692 den= -den; | 692 den= -den; |
| 696 if(nom < 0){ | 696 if(nom < 0){ |
| 697 nom= -nom; | 697 nom= -nom; |
| 698 sign= 1; | 698 sign= 1; |
| 699 } | 699 } |
| 700 | 700 |
| 701 for(;;){ //note is executed 1 or 2 times | 701 gcd = ff_gcd(nom, den); |
| 702 gcd = ff_gcd(nom, den); | 702 nom /= gcd; |
| 703 nom /= gcd; | 703 den /= gcd; |
| 704 den /= gcd; | 704 |
| 705 | 705 if(nom > max || den > max){ |
| 706 larger= FFMAX(nom, den); | 706 AVRational a0={0,1}, a1={1,0}; |
| 707 | 707 exact=0; |
| 708 if(larger > max){ | 708 |
| 709 int64_t div= (larger + max - 1) / max; | 709 for(;;){ |
| 710 nom = (nom + div/2)/div; | 710 int64_t x= nom / den; |
| 711 den = (den + div/2)/div; | 711 int64_t a2n= x*a1.num + a0.num; |
| 712 exact=0; | 712 int64_t a2d= x*a1.den + a0.den; |
| 713 }else | 713 |
| 714 break; | 714 if(a2n > max || a2d > max) break; |
| 715 } | 715 |
| 716 nom %= den; | |
| 717 | |
| 718 a0= a1; | |
| 719 a1= (AVRational){a2n, a2d}; | |
| 720 if(nom==0) break; | |
| 721 x= nom; nom=den; den=x; | |
| 722 } | |
| 723 nom= a1.num; | |
| 724 den= a1.den; | |
| 725 } | |
| 726 | |
| 727 assert(ff_gcd(nom, den) == 1); | |
| 716 | 728 |
| 717 if(sign) nom= -nom; | 729 if(sign) nom= -nom; |
| 718 | 730 |
| 719 *dst_nom = nom; | 731 *dst_nom = nom; |
| 720 *dst_den = den; | 732 *dst_den = den; |
