rational.h (6060B)
1 /* 2 * rational numbers 3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22 /** 23 * @file 24 * @ingroup lavu_math_rational 25 * Utilties for rational number calculation. 26 * @author Michael Niedermayer <michaelni@gmx.at> 27 */ 28 29 #ifndef AVUTIL_RATIONAL_H 30 #define AVUTIL_RATIONAL_H 31 32 #include <stdint.h> 33 #include <limits.h> 34 #include "attributes.h" 35 36 /** 37 * @defgroup lavu_math_rational AVRational 38 * @ingroup lavu_math 39 * Rational number calculation. 40 * 41 * While rational numbers can be expressed as floating-point numbers, the 42 * conversion process is a lossy one, so are floating-point operations. On the 43 * other hand, the nature of FFmpeg demands highly accurate calculation of 44 * timestamps. This set of rational number utilities serves as a generic 45 * interface for manipulating rational numbers as pairs of numerators and 46 * denominators. 47 * 48 * Many of the functions that operate on AVRational's have the suffix `_q`, in 49 * reference to the mathematical symbol "ℚ" (Q) which denotes the set of all 50 * rational numbers. 51 * 52 * @{ 53 */ 54 55 /** 56 * Rational number (pair of numerator and denominator). 57 */ 58 typedef struct AVRational { 59 int num; ///< Numerator 60 int den; ///< Denominator 61 } AVRational; 62 63 /** 64 * Create an AVRational. 65 * 66 * Useful for compilers that do not support compound literals. 67 * 68 * @note The return value is not reduced. 69 * @see av_reduce() 70 */ 71 static inline AVRational av_make_q(int num, int den) { 72 AVRational r = {num, den}; 73 return r; 74 } 75 76 /** 77 * Compare two rationals. 78 * 79 * @param a First rational 80 * @param b Second rational 81 * 82 * @return One of the following values: 83 * - 0 if `a == b` 84 * - 1 if `a > b` 85 * - -1 if `a < b` 86 * - `INT_MIN` if one of the values is of the form `0 / 0` 87 */ 88 static inline int av_cmp_q(AVRational a, AVRational b) { 89 const int64_t tmp = a.num * (int64_t)b.den - b.num * (int64_t)a.den; 90 91 if (tmp) 92 return (int)((tmp ^ a.den ^ b.den) >> 63) | 1; 93 else if (b.den && a.den) 94 return 0; 95 else if (a.num && b.num) 96 return (a.num >> 31) - (b.num >> 31); 97 else 98 return INT_MIN; 99 } 100 101 /** 102 * Convert an AVRational to a `double`. 103 * @param a AVRational to convert 104 * @return `a` in floating-point form 105 * @see av_d2q() 106 */ 107 static inline double av_q2d(AVRational a) { return a.num / (double)a.den; } 108 109 /** 110 * Reduce a fraction. 111 * 112 * This is useful for framerate calculations. 113 * 114 * @param[out] dst_num Destination numerator 115 * @param[out] dst_den Destination denominator 116 * @param[in] num Source numerator 117 * @param[in] den Source denominator 118 * @param[in] max Maximum allowed values for `dst_num` & `dst_den` 119 * @return 1 if the operation is exact, 0 otherwise 120 */ 121 int av_reduce(int* dst_num, int* dst_den, int64_t num, int64_t den, 122 int64_t max); 123 124 /** 125 * Multiply two rationals. 126 * @param b First rational 127 * @param c Second rational 128 * @return b*c 129 */ 130 AVRational av_mul_q(AVRational b, AVRational c) av_const; 131 132 /** 133 * Divide one rational by another. 134 * @param b First rational 135 * @param c Second rational 136 * @return b/c 137 */ 138 AVRational av_div_q(AVRational b, AVRational c) av_const; 139 140 /** 141 * Add two rationals. 142 * @param b First rational 143 * @param c Second rational 144 * @return b+c 145 */ 146 AVRational av_add_q(AVRational b, AVRational c) av_const; 147 148 /** 149 * Subtract one rational from another. 150 * @param b First rational 151 * @param c Second rational 152 * @return b-c 153 */ 154 AVRational av_sub_q(AVRational b, AVRational c) av_const; 155 156 /** 157 * Invert a rational. 158 * @param q value 159 * @return 1 / q 160 */ 161 static av_always_inline AVRational av_inv_q(AVRational q) { 162 AVRational r = {q.den, q.num}; 163 return r; 164 } 165 166 /** 167 * Convert a double precision floating point number to a rational. 168 * 169 * In case of infinity, the returned value is expressed as `{1, 0}` or 170 * `{-1, 0}` depending on the sign. 171 * 172 * @param d `double` to convert 173 * @param max Maximum allowed numerator and denominator 174 * @return `d` in AVRational form 175 * @see av_q2d() 176 */ 177 AVRational av_d2q(double d, int max) av_const; 178 179 /** 180 * Find which of the two rationals is closer to another rational. 181 * 182 * @param q Rational to be compared against 183 * @param q1,q2 Rationals to be tested 184 * @return One of the following values: 185 * - 1 if `q1` is nearer to `q` than `q2` 186 * - -1 if `q2` is nearer to `q` than `q1` 187 * - 0 if they have the same distance 188 */ 189 int av_nearer_q(AVRational q, AVRational q1, AVRational q2); 190 191 /** 192 * Find the value in a list of rationals nearest a given reference rational. 193 * 194 * @param q Reference rational 195 * @param q_list Array of rationals terminated by `{0, 0}` 196 * @return Index of the nearest value found in the array 197 */ 198 int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); 199 200 /** 201 * Convert an AVRational to a IEEE 32-bit `float` expressed in fixed-point 202 * format. 203 * 204 * @param q Rational to be converted 205 * @return Equivalent floating-point value, expressed as an unsigned 32-bit 206 * integer. 207 * @note The returned value is platform-indepedant. 208 */ 209 uint32_t av_q2intfloat(AVRational q); 210 211 /** 212 * Return the best rational so that a and b are multiple of it. 213 * If the resulting denominator is larger than max_den, return def. 214 */ 215 AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def); 216 217 /** 218 * @} 219 */ 220 221 #endif /* AVUTIL_RATIONAL_H */