FFmpeg
Loading...
Searching...
No Matches
rational64.c
Go to the documentation of this file.
1/*
2 * rational numbers
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg 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 * FFmpeg 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 FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
22#include "libavutil/integer.h"
23#include "libavutil/intfloat.h"
24#include "libavutil/log.h"
25#include "libavutil/macros.h"
26
27int main(void)
28{
29 AVRational64 a64,b64,r64;
30 int i;
31 int ret = 0;
32
33 for (a64.num = -2; a64.num <= 2; a64.num++) {
34 for (a64.den = -2; a64.den <= 2; a64.den++) {
35 for (b64.num = -2; b64.num <= 2; b64.num++) {
36 for (b64.den = -2; b64.den <= 2; b64.den++) {
37 const double adbl = ff_q2d_64(a64);
38 const double bdbl = ff_q2d_64(b64);
39 const int c = ff_cmp_q64(a64,b64);
40 const int d = adbl == bdbl ? 0 :
41 adbl > bdbl ? 1 :
42 adbl < bdbl ? -1 : INT_MIN;
43
44 if (c != d) {
45 av_log(NULL, AV_LOG_ERROR, "%lld/%lld %lld/%lld, %d != %d\n",
46 (long long) a64.num, (long long) a64.den,
47 (long long) b64.num, (long long) b64.den, c,d);
48 ret = 1;
49 }
50
51 // Check arithmetic result
52 if (a64.den && b64.den) {
53 double rdbl;
54
55 r64 = ff_add_q64(a64, b64);
56 rdbl = ff_q2d_64(r64);
57 if (rdbl != adbl + bdbl) {
58 av_log(NULL, AV_LOG_ERROR, "%f + %f = %f != %f\n",
59 adbl, bdbl, rdbl, adbl + bdbl);
60 ret = 1;
61 }
62
63 r64 = ff_mul_q64(a64, b64);
64 rdbl = ff_q2d_64(r64);
65 if (rdbl != adbl * bdbl) {
66 av_log(NULL, AV_LOG_ERROR, "%f * %f = %f != %f\n",
67 adbl, bdbl, rdbl, adbl * bdbl);
68 ret = 1;
69 }
70 }
71
72 // Check addition round-trip
73 r64 = ff_sub_q64(ff_add_q64(a64, b64), b64);
74 if (b64.den && (r64.num*a64.den != a64.num*r64.den ||
75 !r64.num != !a64.num ||
76 !r64.den != !a64.den))
77 {
78 av_log(NULL, AV_LOG_ERROR, "%lld/%lld != %lld/%lld\n",
79 (long long) a64.num, (long long) a64.den,
80 (long long) r64.num, (long long) r64.den);
81 ret = 1;
82 }
83
84 if (b64.num) {
85 // Check multiplication round-trip
86 r64 = ff_div_q64(ff_mul_q64(a64, b64), b64);
87 if (b64.den && (r64.num*a64.den != a64.num*r64.den ||
88 !r64.num != !a64.num ||
89 !r64.den != !a64.den))
90 {
91 av_log(NULL, AV_LOG_ERROR, "%lld/%lld != %lld/%lld\n",
92 (long long) a64.num, (long long) a64.den,
93 (long long) r64.num, (long long) r64.den);
94 ret = 1;
95 }
96 }
97 }
98 }
99 }
100 }
101
102 /* Check overflow behavior and edge cases */
103 static const AVRational64 unit_mul_q64[][3] = {
104 {{INT64_MAX, 2}, { 2, 1}, { INT64_MAX, 1}},
105 {{INT64_MAX, 2}, {-2, 1}, {-INT64_MAX, 1}},
106 {{INT64_MAX, 2}, { 0, 1}, {0, 1}},
107 {{INT64_MIN, 2}, { 2, 1}, {-INT64_MAX, 1}}, /* not INT64_MIN */
108 {{INT64_MIN, 2}, {-2, 1}, { INT64_MAX, 1}},
109 {{INT64_MIN, 2}, { 0, 1}, {0, 1}},
110 {{INT64_MAX >> 8, 1}, {INT64_MAX >> 8, 1}, {INT64_MAX, 1}},
111 {{1, INT64_MAX >> 8}, {1, INT64_MAX >> 8}, {0, 1}},
112 {{1, 1}, {0, 0}, {0, 0}},
113 {{0, 1}, {0, 0}, {0, 0}},
114 };
115
116 for (i = 0; i < FF_ARRAY_ELEMS(unit_mul_q64); i++) {
117 for (int c = 0; c < 2; c++) { /* test commutativity */
118 AVRational64 a = unit_mul_q64[i][c ? 1 : 0];
119 AVRational64 b = unit_mul_q64[i][c ? 0 : 1];
120 AVRational64 c = unit_mul_q64[i][2];
122 if (r.num != c.num || r.den != c.den) {
123 av_log(NULL, AV_LOG_ERROR, "%lld/%lld * %lld/%lld = %lld/%lld, expected %lld/%lld\n",
124 (long long) a.num, (long long) a.den,
125 (long long) b.num, (long long) b.den,
126 (long long) r.num, (long long) r.den,
127 (long long) c.num, (long long) c.den);
128 ret = 1;
129 }
130 }
131 }
132
133 static const AVRational64 unit_add_q64[][3] = {
134 {{INT64_MAX, 1}, { 2, 2}, { INT64_MAX, 1}},
135 {{INT64_MAX, 1}, {-2, 2}, { INT64_MAX - 1, 1}},
136 {{INT64_MAX, 1}, { 0, 2}, { INT64_MAX, 1}},
137 {{INT64_MIN, 1}, { 2, 2}, {-INT64_MAX, 1}},
138 {{INT64_MIN, 1}, {-2, 2}, {-INT64_MAX, 1}},
139 {{INT64_MIN, 1}, { 0, 2}, {-INT64_MAX, 1}},
140 {{INT64_MAX - 10, 1}, {20, 1}, { INT64_MAX, 1}},
141 {{2, INT64_MAX}, {2, INT64_MAX}, {4, INT64_MAX}},
142 {{1, 1}, {0, 0}, {0, 0}},
143 {{0, 1}, {0, 0}, {0, 0}},
144 };
145
146 for (i = 0; i < FF_ARRAY_ELEMS(unit_add_q64); i++) {
147 for (int c = 0; c < 2; c++) { /* test commutativity */
148 AVRational64 a = unit_add_q64[i][c ? 1 : 0];
149 AVRational64 b = unit_add_q64[i][c ? 0 : 1];
150 AVRational64 c = unit_add_q64[i][2];
152 if (r.num != c.num || r.den != c.den) {
153 av_log(NULL, AV_LOG_ERROR, "%lld/%lld + %lld/%lld = %lld/%lld, expected %lld/%lld\n",
154 (long long) a.num, (long long) a.den,
155 (long long) b.num, (long long) b.den,
156 (long long) r.num, (long long) r.den,
157 (long long) c.num, (long long) c.den);
158 ret = 1;
159 }
160 }
161 }
162
163 return ret;
164}
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
AVRational64 ff_mul_q64(AVRational64 b, AVRational64 c)
Multiply two 64-bit rationals.
Definition rational64.c:208
AVRational64 ff_sub_q64(AVRational64 b, AVRational64 c)
Subtract one 64-bit rational from another.
Definition rational64.c:232
AVRational64 ff_div_q64(AVRational64 b, AVRational64 c)
Divide one 64-bit rational by another.
Definition rational64.c:217
static double ff_q2d_64(AVRational64 a)
Convert an AVRational64 to a double.
Definition rational64.h:90
AVRational64 ff_add_q64(AVRational64 b, AVRational64 c)
Add two 64-bit rationals.
Definition rational64.c:222
int ff_cmp_q64(AVRational64 a, AVRational64 b)
Compare two 64-bit rationals.
Definition rational64.c:185
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int a
#define r
Definition input.c:42
#define b
Definition input.c:43
arbitrary precision integers
Utility Preprocessor macros.
64-bit rational numbers
#define FF_ARRAY_ELEMS(a)
64-bit Rational number (pair of numerator and denominator).
Definition rational64.h:52
int64_t num
Numerator.
Definition rational64.h:53
int64_t den
Denominator.
Definition rational64.h:54
#define av_log(a,...)
int main(void)
Definition rational64.c:27
static double c[64]