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
32 for (a64.num = -2; a64.num <= 2; a64.num++) {
33 for (a64.den = -2; a64.den <= 2; a64.den++) {
34 for (b64.num = -2; b64.num <= 2; b64.num++) {
35 for (b64.den = -2; b64.den <= 2; b64.den++) {
36 const double adbl = ff_q2d_64(a64);
37 const double bdbl = ff_q2d_64(b64);
38 const int c = ff_cmp_q64(a64,b64);
39 const int d = adbl == bdbl ? 0 :
40 adbl > bdbl ? 1 :
41 adbl < bdbl ? -1 : INT_MIN;
42
43 if (c != d)
44 av_log(NULL, AV_LOG_ERROR, "%lld/%lld %lld/%lld, %d != %d\n",
45 (long long) a64.num, (long long) a64.den,
46 (long long) b64.num, (long long) b64.den, c,d);
47
48 // Check arithmetic result
49 if (a64.den && b64.den) {
50 double rdbl;
51
52 r64 = ff_add_q64(a64, b64);
53 rdbl = ff_q2d_64(r64);
54 if (rdbl != adbl + bdbl) {
55 av_log(NULL, AV_LOG_ERROR, "%f + %f = %f != %f\n",
56 adbl, bdbl, rdbl, adbl + bdbl);
57 }
58
59 r64 = ff_mul_q64(a64, b64);
60 rdbl = ff_q2d_64(r64);
61 if (rdbl != adbl * bdbl) {
62 av_log(NULL, AV_LOG_ERROR, "%f * %f = %f != %f\n",
63 adbl, bdbl, rdbl, adbl * bdbl);
64 }
65 }
66
67 // Check addition round-trip
68 r64 = ff_sub_q64(ff_add_q64(a64, b64), b64);
69 if (b64.den && (r64.num*a64.den != a64.num*r64.den ||
70 !r64.num != !a64.num ||
71 !r64.den != !a64.den))
72 {
73 av_log(NULL, AV_LOG_ERROR, "%lld/%lld != %lld/%lld\n",
74 (long long) a64.num, (long long) a64.den,
75 (long long) r64.num, (long long) r64.den);
76 }
77
78 if (b64.num) {
79 // Check multiplication round-trip
80 r64 = ff_div_q64(ff_mul_q64(a64, b64), b64);
81 if (b64.den && (r64.num*a64.den != a64.num*r64.den ||
82 !r64.num != !a64.num ||
83 !r64.den != !a64.den))
84 {
85 av_log(NULL, AV_LOG_ERROR, "%lld/%lld != %lld/%lld\n",
86 (long long) a64.num, (long long) a64.den,
87 (long long) r64.num, (long long) r64.den);
88 }
89 }
90 }
91 }
92 }
93 }
94
95 /* Check overflow behavior and edge cases */
96 static const AVRational64 unit_mul_q64[][3] = {
97 {{INT64_MAX, 2}, { 2, 1}, { INT64_MAX, 1}},
98 {{INT64_MAX, 2}, {-2, 1}, {-INT64_MAX, 1}},
99 {{INT64_MAX, 2}, { 0, 1}, {0, 1}},
100 {{INT64_MIN, 2}, { 2, 1}, {-INT64_MAX, 1}}, /* not INT64_MIN */
101 {{INT64_MIN, 2}, {-2, 1}, { INT64_MAX, 1}},
102 {{INT64_MIN, 2}, { 0, 1}, {0, 1}},
103 {{INT64_MAX >> 8, 1}, {INT64_MAX >> 8, 1}, {INT64_MAX, 1}},
104 {{1, INT64_MAX >> 8}, {1, INT64_MAX >> 8}, {0, 1}},
105 {{1, 1}, {0, 0}, {0, 0}},
106 {{0, 1}, {0, 0}, {0, 0}},
107 };
108
109 for (i = 0; i < FF_ARRAY_ELEMS(unit_mul_q64); i++) {
110 for (int c = 0; c < 2; c++) { /* test commutativity */
111 AVRational64 a = unit_mul_q64[i][c ? 1 : 0];
112 AVRational64 b = unit_mul_q64[i][c ? 0 : 1];
113 AVRational64 c = unit_mul_q64[i][2];
115 if (r.num != c.num || r.den != c.den) {
116 av_log(NULL, AV_LOG_ERROR, "%lld/%lld * %lld/%lld = %lld/%lld, expected %lld/%lld\n",
117 (long long) a.num, (long long) a.den,
118 (long long) b.num, (long long) b.den,
119 (long long) r.num, (long long) r.den,
120 (long long) c.num, (long long) c.den);
121 }
122 }
123 }
124
125 static const AVRational64 unit_add_q64[][3] = {
126 {{INT64_MAX, 1}, { 2, 2}, { INT64_MAX, 1}},
127 {{INT64_MAX, 1}, {-2, 2}, { INT64_MAX - 1, 1}},
128 {{INT64_MAX, 1}, { 0, 2}, { INT64_MAX, 1}},
129 {{INT64_MIN, 1}, { 2, 2}, {-INT64_MAX, 1}},
130 {{INT64_MIN, 1}, {-2, 2}, {-INT64_MAX, 1}},
131 {{INT64_MIN, 1}, { 0, 2}, {-INT64_MAX, 1}},
132 {{INT64_MAX - 10, 1}, {20, 1}, { INT64_MAX, 1}},
133 {{2, INT64_MAX}, {2, INT64_MAX}, {4, INT64_MAX}},
134 {{1, 1}, {0, 0}, {0, 0}},
135 {{0, 1}, {0, 0}, {0, 0}},
136 };
137
138 for (i = 0; i < FF_ARRAY_ELEMS(unit_add_q64); i++) {
139 for (int c = 0; c < 2; c++) { /* test commutativity */
140 AVRational64 a = unit_add_q64[i][c ? 1 : 0];
141 AVRational64 b = unit_add_q64[i][c ? 0 : 1];
142 AVRational64 c = unit_add_q64[i][2];
144 if (r.num != c.num || r.den != c.den) {
145 av_log(NULL, AV_LOG_ERROR, "%lld/%lld + %lld/%lld = %lld/%lld, expected %lld/%lld\n",
146 (long long) a.num, (long long) a.den,
147 (long long) b.num, (long long) b.den,
148 (long long) r.num, (long long) r.den,
149 (long long) c.num, (long long) c.den);
150 }
151 }
152 }
153
154 return 0;
155}
#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:124
AVRational64 ff_sub_q64(AVRational64 b, AVRational64 c)
Subtract one 64-bit rational from another.
Definition rational64.c:141
AVRational64 ff_div_q64(AVRational64 b, AVRational64 c)
Divide one 64-bit rational by another.
Definition rational64.c:130
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:135
int ff_cmp_q64(AVRational64 a, AVRational64 b)
Compare two 64-bit rationals.
Definition rational64.c:108
#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]