annotate mathematics.c @ 41:e2d207b1cb8e libavutil

improve selftest
author michael
date Mon, 29 May 2006 19:44:17 +0000
parents 205312eb9c6e
children d76a36742464
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
1 /*
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
2 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
3 *
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
4 * This library is free software; you can redistribute it and/or
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
5 * modify it under the terms of the GNU Lesser General Public
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
6 * License as published by the Free Software Foundation; either
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
7 * version 2 of the License, or (at your option) any later version.
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
8 *
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
9 * This library is distributed in the hope that it will be useful,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
12 * Lesser General Public License for more details.
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
13 *
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
14 * You should have received a copy of the GNU Lesser General Public
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
15 * License along with this library; if not, write to the Free Software
15
af59e84e283d Update licensing information: The FSF changed postal address.
diego
parents: 12
diff changeset
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
17 */
12
ce8f9f4390c3 COSMETICS: Remove all trailing whitespace.
diego
parents: 0
diff changeset
18
0
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
19 /**
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
20 * @file mathematics.c
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
21 * Miscellaneous math routines and tables.
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
22 */
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
23
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
24 #include "common.h"
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
25 #include "mathematics.h"
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
26
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
27 const uint8_t ff_sqrt_tab[128]={
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
28 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
29 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
30 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
31 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
32 };
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
33
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
34 const uint8_t ff_log2_tab[256]={
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
35 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
36 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
37 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
38 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
39 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
40 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
41 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
42 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
43 };
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
44
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
45 int64_t ff_gcd(int64_t a, int64_t b){
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
46 if(b) return ff_gcd(b, a%b);
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
47 else return a;
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
48 }
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
49
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
50 int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
51 int64_t r=0;
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
52 assert(c > 0);
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
53 assert(b >=0);
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
54 assert(rnd >=0 && rnd<=5 && rnd!=4);
12
ce8f9f4390c3 COSMETICS: Remove all trailing whitespace.
diego
parents: 0
diff changeset
55
ce8f9f4390c3 COSMETICS: Remove all trailing whitespace.
diego
parents: 0
diff changeset
56 if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1));
ce8f9f4390c3 COSMETICS: Remove all trailing whitespace.
diego
parents: 0
diff changeset
57
0
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
58 if(rnd==AV_ROUND_NEAR_INF) r= c/2;
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
59 else if(rnd&1) r= c-1;
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
60
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
61 if(b<=INT_MAX && c<=INT_MAX){
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
62 if(a<=INT_MAX)
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
63 return (a * b + r)/c;
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
64 else
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
65 return a/c*b + (a%c*b + r)/c;
34
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
66 }else{
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
67 #if 1
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
68 uint64_t a0= a&0xFFFFFFFF;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
69 uint64_t a1= a>>32;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
70 uint64_t b0= b&0xFFFFFFFF;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
71 uint64_t b1= b>>32;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
72 uint64_t t1= a0*b1 + a1*b0;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
73 uint64_t t1a= t1<<32;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
74 int i;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
75
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
76 a0 = a0*b0 + t1a;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
77 a1 = a1*b1 + (t1>>32) + (a0<t1a);
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
78 a0 += r;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
79 a1 += a0<r;
12
ce8f9f4390c3 COSMETICS: Remove all trailing whitespace.
diego
parents: 0
diff changeset
80
34
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
81 for(i=63; i>=0; i--){
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
82 // int o= a1 & 0x8000000000000000ULL;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
83 a1+= a1 + ((a0>>i)&1);
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
84 t1+=t1;
36
8795371b6c88 <= vs. >= 10l bug
michael
parents: 35
diff changeset
85 if(/*o || */c <= a1){
34
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
86 a1 -= c;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
87 t1++;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
88 }
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
89 }
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
90 return t1;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
91 }
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
92 #else
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
93 AVInteger ai;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
94 ai= av_mul_i(av_int2i(a), av_int2i(b));
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
95 ai= av_add_i(ai, av_int2i(r));
12
ce8f9f4390c3 COSMETICS: Remove all trailing whitespace.
diego
parents: 0
diff changeset
96
34
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
97 return av_i2int(av_div_i(ai, av_int2i(c)));
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
98 }
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
99 #endif
0
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
100 }
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
101
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
102 int64_t av_rescale(int64_t a, int64_t b, int64_t c){
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
103 return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF);
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
104 }
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
105
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
106 int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq){
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
107 int64_t b= bq.num * (int64_t)cq.den;
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
108 int64_t c= cq.num * (int64_t)bq.den;
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
109 return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF);
ee8f44bb7c4d libavutil: Utility code from libavcodec moved to a separate library.
al
parents:
diff changeset
110 }
34
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
111 #if 0
41
e2d207b1cb8e improve selftest
michael
parents: 37
diff changeset
112 #include "integer.h"
36
8795371b6c88 <= vs. >= 10l bug
michael
parents: 35
diff changeset
113 #undef printf
34
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
114 main(){
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
115 int64_t a,b,c,d,e;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
116
41
e2d207b1cb8e improve selftest
michael
parents: 37
diff changeset
117 for(a=7; a<(1LL<<62); a+=a/3+1){
e2d207b1cb8e improve selftest
michael
parents: 37
diff changeset
118 for(b=3; b<(1LL<<62); b+=b/4+1){
e2d207b1cb8e improve selftest
michael
parents: 37
diff changeset
119 for(c=9; c<(1LL<<62); c+=(c*2)/5+3){
34
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
120 int64_t r= c/2;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
121 AVInteger ai;
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
122 ai= av_mul_i(av_int2i(a), av_int2i(b));
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
123 ai= av_add_i(ai, av_int2i(r));
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
124
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
125 d= av_i2int(av_div_i(ai, av_int2i(c)));
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
126
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
127 e= av_rescale(a,b,c);
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
128
36
8795371b6c88 <= vs. >= 10l bug
michael
parents: 35
diff changeset
129 if((double)a * (double)b / (double)c > (1LL<<63))
8795371b6c88 <= vs. >= 10l bug
michael
parents: 35
diff changeset
130 continue;
8795371b6c88 <= vs. >= 10l bug
michael
parents: 35
diff changeset
131
8795371b6c88 <= vs. >= 10l bug
michael
parents: 35
diff changeset
132 if(d!=e) printf("%Ld*%Ld/%Ld= %Ld=%Ld\n", a, b, c, d, e);
34
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
133 }
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
134 }
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
135 }
dedc1568e2cf avoid AVInteger usage in av_rescale
michael
parents: 15
diff changeset
136 }
35
b734d9f69ff4 add newline at end of file
mru
parents: 34
diff changeset
137 #endif