Libav
mathematics.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
26 #include <stdint.h>
27 #include <limits.h>
28 
29 #include "mathematics.h"
30 #include "version.h"
31 
32 int64_t av_gcd(int64_t a, int64_t b)
33 {
34  if (b)
35  return av_gcd(b, a % b);
36  else
37  return a;
38 }
39 
40 int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
41 {
42  int64_t r = 0;
43 
44  if (c <= 0 || b < 0 || rnd == 4 || rnd > 5)
45  return INT64_MIN;
46 
47  if (a < 0 && a != INT64_MIN)
48  return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd >> 1) & 1));
49 
50  if (rnd == AV_ROUND_NEAR_INF)
51  r = c / 2;
52  else if (rnd & 1)
53  r = c - 1;
54 
55  if (b <= INT_MAX && c <= INT_MAX) {
56  if (a <= INT_MAX)
57  return (a * b + r) / c;
58  else
59  return a / c * b + (a % c * b + r) / c;
60  } else {
61  uint64_t a0 = a & 0xFFFFFFFF;
62  uint64_t a1 = a >> 32;
63  uint64_t b0 = b & 0xFFFFFFFF;
64  uint64_t b1 = b >> 32;
65  uint64_t t1 = a0 * b1 + a1 * b0;
66  uint64_t t1a = t1 << 32;
67  int i;
68 
69  a0 = a0 * b0 + t1a;
70  a1 = a1 * b1 + (t1 >> 32) + (a0 < t1a);
71  a0 += r;
72  a1 += a0 < r;
73 
74  for (i = 63; i >= 0; i--) {
75  a1 += a1 + ((a0 >> i) & 1);
76  t1 += t1;
77  if (c <= a1) {
78  a1 -= c;
79  t1++;
80  }
81  }
82  return t1;
83  }
84 }
85 
86 int64_t av_rescale(int64_t a, int64_t b, int64_t c)
87 {
88  return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF);
89 }
90 
91 int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq,
92  enum AVRounding rnd)
93 {
94  int64_t b = bq.num * (int64_t)cq.den;
95  int64_t c = cq.num * (int64_t)bq.den;
96  return av_rescale_rnd(a, b, c, rnd);
97 }
98 
99 int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
100 {
101  return av_rescale_q_rnd(a, bq, cq, AV_ROUND_NEAR_INF);
102 }
103 
104 int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
105 {
106  int64_t a = tb_a.num * (int64_t)tb_b.den;
107  int64_t b = tb_b.num * (int64_t)tb_a.den;
108  if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b)
109  return -1;
110  if (av_rescale_rnd(ts_b, b, a, AV_ROUND_DOWN) < ts_a)
111  return 1;
112  return 0;
113 }
114 
115 int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod)
116 {
117  int64_t c = (a - b) & (mod - 1);
118  if (c > (mod >> 1))
119  c -= mod;
120  return c;
121 }
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:40
int num
numerator
Definition: rational.h:44
AVRounding
Definition: mathematics.h:49
#define b
Definition: input.c:52
#define r
Definition: input.c:51
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:99
Round to nearest and halfway cases away from zero.
Definition: mathematics.h:54
int64_t av_gcd(int64_t a, int64_t b)
Return the greatest common divisor of a and b.
Definition: mathematics.c:32
Libavutil version macros.
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
Compare 2 timestamps each in its own timebases.
Definition: mathematics.c:104
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding rnd)
Rescale a 64-bit integer by 2 rational numbers with specified rounding.
Definition: mathematics.c:91
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:86
rational number numerator/denominator
Definition: rational.h:43
Round toward -infinity.
Definition: mathematics.h:52
#define rnd()
Definition: checkasm.h:65
int den
denominator
Definition: rational.h:45
int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod)
Compare 2 integers modulo mod.
Definition: mathematics.c:115