mathops.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #include "internal.h"
  2. #include "mathops.h"
  3. /*The fastest fallback strategy for platforms with fast multiplication appears
  4. to be based on de Bruijn sequences~\cite{LP98}.
  5. Define OC_ILOG_NODEBRUIJN to use a simpler fallback on platforms where
  6. multiplication or table lookups are too expensive.
  7. @UNPUBLISHED{LP98,
  8. author="Charles E. Leiserson and Harald Prokop",
  9. title="Using de {Bruijn} Sequences to Index a 1 in a Computer Word",
  10. month=Jun,
  11. year=1998,
  12. note="\url{http://supertech.csail.mit.edu/papers/debruijn.pdf}"
  13. }*/
  14. #if !defined(OC_ILOG_NODEBRUIJN)&&!defined(OC_CLZ32)
  15. static const unsigned char OC_DEBRUIJN_IDX32[32]={
  16. 0, 1,28, 2,29,14,24, 3,30,22,20,15,25,17, 4, 8,
  17. 31,27,13,23,21,19,16, 7,26,12,18, 6,11, 5,10, 9
  18. };
  19. #endif
  20. int oc_ilog32(ogg_uint32_t _v){
  21. #if defined(OC_CLZ32)
  22. return OC_CLZ32_OFFS-OC_CLZ32(_v)&-!!_v;
  23. #else
  24. /*On a Pentium M, this branchless version tested as the fastest version without
  25. multiplications on 1,000,000,000 random 32-bit integers, edging out a
  26. similar version with branches, and a 256-entry LUT version.*/
  27. # if defined(OC_ILOG_NODEBRUIJN)
  28. int ret;
  29. int m;
  30. ret=_v>0;
  31. m=(_v>0xFFFFU)<<4;
  32. _v>>=m;
  33. ret|=m;
  34. m=(_v>0xFFU)<<3;
  35. _v>>=m;
  36. ret|=m;
  37. m=(_v>0xFU)<<2;
  38. _v>>=m;
  39. ret|=m;
  40. m=(_v>3)<<1;
  41. _v>>=m;
  42. ret|=m;
  43. ret+=_v>1;
  44. return ret;
  45. /*This de Bruijn sequence version is faster if you have a fast multiplier.*/
  46. # else
  47. int ret;
  48. _v|=_v>>1;
  49. _v|=_v>>2;
  50. _v|=_v>>4;
  51. _v|=_v>>8;
  52. _v|=_v>>16;
  53. ret=_v&1;
  54. _v=(_v>>1)+1;
  55. ret+=OC_DEBRUIJN_IDX32[_v*0x77CB531U>>27&0x1F];
  56. return ret;
  57. # endif
  58. #endif
  59. }
  60. int oc_ilog64(ogg_int64_t _v){
  61. #if defined(OC_CLZ64)
  62. return OC_CLZ64_OFFS-OC_CLZ64(_v)&-!!_v;
  63. #else
  64. /*If we don't have a fast 64-bit word implementation, split it into two 32-bit
  65. halves.*/
  66. # if defined(OC_ILOG_NODEBRUIJN)|| \
  67. defined(OC_CLZ32)||LONG_MAX<9223372036854775807LL
  68. ogg_uint32_t v;
  69. int ret;
  70. int m;
  71. m=(_v>0xFFFFFFFFU)<<5;
  72. v=(ogg_uint32_t)(_v>>m);
  73. # if defined(OC_CLZ32)
  74. ret=m+OC_CLZ32_OFFS-OC_CLZ32(v)&-!!v;
  75. # elif defined(OC_ILOG_NODEBRUIJN)
  76. ret=v>0|m;
  77. m=(v>0xFFFFU)<<4;
  78. v>>=m;
  79. ret|=m;
  80. m=(v>0xFFU)<<3;
  81. v>>=m;
  82. ret|=m;
  83. m=(v>0xFU)<<2;
  84. v>>=m;
  85. ret|=m;
  86. m=(v>3)<<1;
  87. v>>=m;
  88. ret|=m;
  89. ret+=v>1;
  90. return ret;
  91. # else
  92. v|=v>>1;
  93. v|=v>>2;
  94. v|=v>>4;
  95. v|=v>>8;
  96. v|=v>>16;
  97. ret=v&1|m;
  98. v=(v>>1)+1;
  99. ret+=OC_DEBRUIJN_IDX32[v*0x77CB531U>>27&0x1F];
  100. # endif
  101. return ret;
  102. /*Otherwise do it in one 64-bit multiply.*/
  103. # else
  104. static const unsigned char OC_DEBRUIJN_IDX64[64]={
  105. 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40,
  106. 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57,
  107. 63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56,
  108. 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58
  109. };
  110. int ret;
  111. _v|=_v>>1;
  112. _v|=_v>>2;
  113. _v|=_v>>4;
  114. _v|=_v>>8;
  115. _v|=_v>>16;
  116. _v|=_v>>32;
  117. ret=(int)_v&1;
  118. _v=(_v>>1)+1;
  119. ret+=OC_DEBRUIJN_IDX64[_v*0x218A392CD3D5DBF>>58&0x3F];
  120. return ret;
  121. # endif
  122. #endif
  123. }
  124. /*round(2**(62+i)*atanh(2**(-(i+1)))/log(2))*/
  125. static const ogg_int64_t OC_ATANH_LOG2[32]={
  126. 0x32B803473F7AD0F4LL,0x2F2A71BD4E25E916LL,0x2E68B244BB93BA06LL,
  127. 0x2E39FB9198CE62E4LL,0x2E2E683F68565C8FLL,0x2E2B850BE2077FC1LL,
  128. 0x2E2ACC58FE7B78DBLL,0x2E2A9E2DE52FD5F2LL,0x2E2A92A338D53EECLL,
  129. 0x2E2A8FC08F5E19B6LL,0x2E2A8F07E51A485ELL,0x2E2A8ED9BA8AF388LL,
  130. 0x2E2A8ECE2FE7384ALL,0x2E2A8ECB4D3E4B1ALL,0x2E2A8ECA94940FE8LL,
  131. 0x2E2A8ECA6669811DLL,0x2E2A8ECA5ADEDD6ALL,0x2E2A8ECA57FC347ELL,
  132. 0x2E2A8ECA57438A43LL,0x2E2A8ECA57155FB4LL,0x2E2A8ECA5709D510LL,
  133. 0x2E2A8ECA5706F267LL,0x2E2A8ECA570639BDLL,0x2E2A8ECA57060B92LL,
  134. 0x2E2A8ECA57060008LL,0x2E2A8ECA5705FD25LL,0x2E2A8ECA5705FC6CLL,
  135. 0x2E2A8ECA5705FC3ELL,0x2E2A8ECA5705FC33LL,0x2E2A8ECA5705FC30LL,
  136. 0x2E2A8ECA5705FC2FLL,0x2E2A8ECA5705FC2FLL
  137. };
  138. /*Computes the binary exponential of _z, a log base 2 in Q57 format.*/
  139. ogg_int64_t oc_bexp64(ogg_int64_t _z){
  140. ogg_int64_t w;
  141. ogg_int64_t z;
  142. int ipart;
  143. ipart=(int)(_z>>57);
  144. if(ipart<0)return 0;
  145. if(ipart>=63)return 0x7FFFFFFFFFFFFFFFLL;
  146. z=_z-OC_Q57(ipart);
  147. if(z){
  148. ogg_int64_t mask;
  149. long wlo;
  150. int i;
  151. /*C doesn't give us 64x64->128 muls, so we use CORDIC.
  152. This is not particularly fast, but it's not being used in time-critical
  153. code; it is very accurate.*/
  154. /*z is the fractional part of the log in Q62 format.
  155. We need 1 bit of headroom since the magnitude can get larger than 1
  156. during the iteration, and a sign bit.*/
  157. z<<=5;
  158. /*w is the exponential in Q61 format (since it also needs headroom and can
  159. get as large as 2.0); we could get another bit if we dropped the sign,
  160. but we'll recover that bit later anyway.
  161. Ideally this should start out as
  162. \lim_{n->\infty} 2^{61}/\product_{i=1}^n \sqrt{1-2^{-2i}}
  163. but in order to guarantee convergence we have to repeat iterations 4,
  164. 13 (=3*4+1), and 40 (=3*13+1, etc.), so it winds up somewhat larger.*/
  165. w=0x26A3D0E401DD846DLL;
  166. for(i=0;;i++){
  167. mask=-(z<0);
  168. w+=(w>>i+1)+mask^mask;
  169. z-=OC_ATANH_LOG2[i]+mask^mask;
  170. /*Repeat iteration 4.*/
  171. if(i>=3)break;
  172. z<<=1;
  173. }
  174. for(;;i++){
  175. mask=-(z<0);
  176. w+=(w>>i+1)+mask^mask;
  177. z-=OC_ATANH_LOG2[i]+mask^mask;
  178. /*Repeat iteration 13.*/
  179. if(i>=12)break;
  180. z<<=1;
  181. }
  182. for(;i<32;i++){
  183. mask=-(z<0);
  184. w+=(w>>i+1)+mask^mask;
  185. z=z-(OC_ATANH_LOG2[i]+mask^mask)<<1;
  186. }
  187. wlo=0;
  188. /*Skip the remaining iterations unless we really require that much
  189. precision.
  190. We could have bailed out earlier for smaller iparts, but that would
  191. require initializing w from a table, as the limit doesn't converge to
  192. 61-bit precision until n=30.*/
  193. if(ipart>30){
  194. /*For these iterations, we just update the low bits, as the high bits
  195. can't possibly be affected.
  196. OC_ATANH_LOG2 has also converged (it actually did so one iteration
  197. earlier, but that's no reason for an extra special case).*/
  198. for(;;i++){
  199. mask=-(z<0);
  200. wlo+=(w>>i)+mask^mask;
  201. z-=OC_ATANH_LOG2[31]+mask^mask;
  202. /*Repeat iteration 40.*/
  203. if(i>=39)break;
  204. z<<=1;
  205. }
  206. for(;i<61;i++){
  207. mask=-(z<0);
  208. wlo+=(w>>i)+mask^mask;
  209. z=z-(OC_ATANH_LOG2[31]+mask^mask)<<1;
  210. }
  211. }
  212. w=(w<<1)+wlo;
  213. }
  214. else w=(ogg_int64_t)1<<62;
  215. if(ipart<62)w=(w>>61-ipart)+1>>1;
  216. return w;
  217. }
  218. /*Computes the binary logarithm of _w, returned in Q57 format.*/
  219. ogg_int64_t oc_blog64(ogg_int64_t _w){
  220. ogg_int64_t z;
  221. int ipart;
  222. if(_w<=0)return -1;
  223. ipart=OC_ILOGNZ_64(_w)-1;
  224. if(ipart>61)_w>>=ipart-61;
  225. else _w<<=61-ipart;
  226. z=0;
  227. if(_w&_w-1){
  228. ogg_int64_t x;
  229. ogg_int64_t y;
  230. ogg_int64_t u;
  231. ogg_int64_t mask;
  232. int i;
  233. /*C doesn't give us 64x64->128 muls, so we use CORDIC.
  234. This is not particularly fast, but it's not being used in time-critical
  235. code; it is very accurate.*/
  236. /*z is the fractional part of the log in Q61 format.*/
  237. /*x and y are the cosh() and sinh(), respectively, in Q61 format.
  238. We are computing z=2*atanh(y/x)=2*atanh((_w-1)/(_w+1)).*/
  239. x=_w+((ogg_int64_t)1<<61);
  240. y=_w-((ogg_int64_t)1<<61);
  241. for(i=0;i<4;i++){
  242. mask=-(y<0);
  243. z+=(OC_ATANH_LOG2[i]>>i)+mask^mask;
  244. u=x>>i+1;
  245. x-=(y>>i+1)+mask^mask;
  246. y-=u+mask^mask;
  247. }
  248. /*Repeat iteration 4.*/
  249. for(i--;i<13;i++){
  250. mask=-(y<0);
  251. z+=(OC_ATANH_LOG2[i]>>i)+mask^mask;
  252. u=x>>i+1;
  253. x-=(y>>i+1)+mask^mask;
  254. y-=u+mask^mask;
  255. }
  256. /*Repeat iteration 13.*/
  257. for(i--;i<32;i++){
  258. mask=-(y<0);
  259. z+=(OC_ATANH_LOG2[i]>>i)+mask^mask;
  260. u=x>>i+1;
  261. x-=(y>>i+1)+mask^mask;
  262. y-=u+mask^mask;
  263. }
  264. /*OC_ATANH_LOG2 has converged.*/
  265. for(;i<40;i++){
  266. mask=-(y<0);
  267. z+=(OC_ATANH_LOG2[31]>>i)+mask^mask;
  268. u=x>>i+1;
  269. x-=(y>>i+1)+mask^mask;
  270. y-=u+mask^mask;
  271. }
  272. /*Repeat iteration 40.*/
  273. for(i--;i<62;i++){
  274. mask=-(y<0);
  275. z+=(OC_ATANH_LOG2[31]>>i)+mask^mask;
  276. u=x>>i+1;
  277. x-=(y>>i+1)+mask^mask;
  278. y-=u+mask^mask;
  279. }
  280. z=z+8>>4;
  281. }
  282. return OC_Q57(ipart)+z;
  283. }
  284. /*Polynomial approximation of a binary exponential.
  285. Q10 input, Q0 output.*/
  286. ogg_uint32_t oc_bexp32_q10(int _z){
  287. unsigned n;
  288. int ipart;
  289. ipart=_z>>10;
  290. n=(_z&(1<<10)-1)<<4;
  291. n=(n*((n*((n*((n*3548>>15)+6817)>>15)+15823)>>15)+22708)>>15)+16384;
  292. return 14-ipart>0?n+(1<<13-ipart)>>14-ipart:n<<ipart-14;
  293. }
  294. /*Polynomial approximation of a binary logarithm.
  295. Q0 input, Q10 output.*/
  296. int oc_blog32_q10(ogg_uint32_t _w){
  297. int n;
  298. int ipart;
  299. int fpart;
  300. if(_w<=0)return -1;
  301. ipart=OC_ILOGNZ_32(_w);
  302. n=(ipart-16>0?_w>>ipart-16:_w<<16-ipart)-32768-16384;
  303. fpart=(n*((n*((n*((n*-1402>>15)+2546)>>15)-5216)>>15)+15745)>>15)-6793;
  304. return (ipart<<10)+(fpart>>4);
  305. }