Example #1
0
        public static int av_reduce(/*int *dst_num, int *dst_den,*/int[] num_den, long num, long den, long max)
        {
            AVRational a0 = new AVRational(0, 1);
            AVRational a1 = new AVRational(1, 0);
            int sign = ((num < 0) ^ (den < 0)) ? 1 : 0;
            long gcd = av_gcd(Math.Abs(num), Math.Abs(den));

            if (gcd != 0)
            {
                num = Math.Abs(num) / gcd;
                den = Math.Abs(den) / gcd;
            }
            if (num <= max && den <= max)
            {
                a1 = new AVRational(num, den);
                den = 0;
            }

            while (den != 0)
            {
                /*uint64_t*/
                long x = num / den;
                long next_den = num - den * x;
                long a2n = x * a1.num + a0.num;
                long a2d = x * a1.den + a0.den;

                if (a2n > max || a2d > max)
                {
                    if (a1.num != 0) x = (max - a0.num) / a1.num;
                    if (a1.den != 0) x = Math.Min(x, (max - a0.den) / a1.den);

                    if (den * (2 * x * a1.den + a0.den) > num * a1.den)
                        a1 = new AVRational(x * a1.num + a0.num, x * a1.den + a0.den);
                    break;
                }

                a0 = a1;
                a1 = new AVRational(a2n, a2d);
                num = den;
                den = next_den;
            }
            //av_assert2(av_gcd(a1.num, a1.den) <= 1U);

            num_den[0] = ((sign != 0) ? -a1.num : a1.num);
            num_den[1] = a1.den;

            return (den == 0 ? 1 : 0);
        }
Example #2
0
        /**
         * Compare two rationals.
         * @param a first rational
         * @param b second rational
         * @return 0 if a==b, 1 if a>b, -1 if a<b, and INT_MIN if one of the
         * values is of the form 0/0
         */
        /*inline*/
        public static int av_cmp_q(AVRational a, AVRational b)
        {
            long tmp = a.num * (long)b.den - b.num * (long)a.den;

            if (tmp != 0) return (int)(((tmp ^ a.den ^ b.den) >> 63) | 1);
            else if (b.den != 0 && a.den != 0) return 0;
            else if (a.num != 0 && b.num != 0) return (a.num >> 31) - (b.num >> 31);
            else return int.MinValue;
        }