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; |