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#include "libavutil/rational.c" 23#include "libavutil/integer.h" 24 25int main(void) 26{ 27 AVRational a,b,r; 28 int i,j,k; 29 static const int64_t numlist[] = { 30 INT64_MIN, INT64_MIN+1, INT64_MAX, INT32_MIN, INT32_MAX, 1,0,-1, 31 123456789, INT32_MAX-1, INT32_MAX+1LL, UINT32_MAX-1, UINT32_MAX, UINT32_MAX+1LL 32 }; 33 34 for (a.num = -2; a.num <= 2; a.num++) { 35 for (a.den = -2; a.den <= 2; a.den++) { 36 for (b.num = -2; b.num <= 2; b.num++) { 37 for (b.den = -2; b.den <= 2; b.den++) { 38 int c = av_cmp_q(a,b); 39 double d = av_q2d(a) == av_q2d(b) ? 40 0 : (av_q2d(a) - av_q2d(b)); 41 if (d > 0) d = 1; 42 else if (d < 0) d = -1; 43 else if (d != d) d = INT_MIN; 44 if (c != d) 45 av_log(NULL, AV_LOG_ERROR, "%d/%d %d/%d, %d %f\n", a.num, 46 a.den, b.num, b.den, c,d); 47 r = av_sub_q(av_add_q(b,a), b); 48 if(b.den && (r.num*a.den != a.num*r.den || !r.num != !a.num || !r.den != !a.den)) 49 av_log(NULL, AV_LOG_ERROR, "%d/%d ", r.num, r.den); 50 } 51 } 52 } 53 } 54 55 for (i = 0; i < FF_ARRAY_ELEMS(numlist); i++) { 56 int64_t a = numlist[i]; 57 58 for (j = 0; j < FF_ARRAY_ELEMS(numlist); j++) { 59 int64_t b = numlist[j]; 60 if (b<=0) 61 continue; 62 for (k = 0; k < FF_ARRAY_ELEMS(numlist); k++) { 63 int64_t c = numlist[k]; 64 int64_t res; 65 AVInteger ai; 66 67 if (c<=0) 68 continue; 69 res = av_rescale_rnd(a,b,c, AV_ROUND_ZERO); 70 71 ai = av_mul_i(av_int2i(a), av_int2i(b)); 72 ai = av_div_i(ai, av_int2i(c)); 73 74 if (av_cmp_i(ai, av_int2i(INT64_MAX)) > 0 && res == INT64_MIN) 75 continue; 76 if (av_cmp_i(ai, av_int2i(INT64_MIN)) < 0 && res == INT64_MIN) 77 continue; 78 if (av_cmp_i(ai, av_int2i(res)) == 0) 79 continue; 80 81 // Special exception for INT64_MIN, remove this in case INT64_MIN is handled without off by 1 error 82 if (av_cmp_i(ai, av_int2i(res-1)) == 0 && a == INT64_MIN) 83 continue; 84 85 av_log(NULL, AV_LOG_ERROR, "%"PRId64" * %"PRId64" / %"PRId64" = %"PRId64" or %"PRId64"\n", a,b,c, res, av_i2int(ai)); 86 } 87 } 88 } 89 90 for (a.num = 1; a.num <= 10; a.num++) { 91 for (a.den = 1; a.den <= 10; a.den++) { 92 if (av_gcd(a.num, a.den) > 1) 93 continue; 94 for (b.num = 1; b.num <= 10; b.num++) { 95 for (b.den = 1; b.den <= 10; b.den++) { 96 int start; 97 if (av_gcd(b.num, b.den) > 1) 98 continue; 99 if (av_cmp_q(b, a) < 0) 100 continue; 101 for (start = 0; start < 10 ; start++) { 102 int acc= start; 103 int i; 104 105 for (i = 0; i<100; i++) { 106 int exact = start + av_rescale_q(i+1, b, a); 107 acc = av_add_stable(a, acc, b, 1); 108 if (FFABS(acc - exact) > 2) { 109 av_log(NULL, AV_LOG_ERROR, "%d/%d %d/%d, %d %d\n", a.num, 110 a.den, b.num, b.den, acc, exact); 111 return 1; 112 } 113 } 114 } 115 } 116 } 117 } 118 } 119 120 for (a.den = 1; a.den < 0x100000000U/3; a.den*=3) { 121 for (a.num = -1; a.num < (1<<27); a.num += 1 + a.num/100) { 122 float f = av_int2float(av_q2intfloat(a)); 123 float f2 = av_q2d(a); 124 if (fabs(f - f2) > fabs(f)/5000000) { 125 av_log(NULL, AV_LOG_ERROR, "%d/%d %f %f\n", a.num, 126 a.den, f, f2); 127 return 1; 128 } 129 130 } 131 } 132 133 return 0; 134} 135