You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
2.5KB

  1. //copyright Michael Niedermayer 2006 license:LGPL
  2. #define MIN_EXP -126
  3. #define MAX_EXP 126
  4. #define ONE_BITS 29
  5. typedef struct SoftFloat{
  6. int32_t exp;
  7. int32_t mant;
  8. }SoftFloat;
  9. static SoftFloat av_normalize_sf(SoftFloat a){
  10. if(a.mant){
  11. #if 1
  12. while((a.mant + 0x20000000U)<0x40000000U){
  13. a.mant += a.mant;
  14. a.exp -= 1;
  15. }
  16. #else
  17. int s=ONE_BITS + 1 - av_log2(a.mant ^ (a.mant<<1));
  18. a.exp -= s;
  19. a.mant <<= s;
  20. #endif
  21. if(a.exp < MIN_EXP){
  22. a.exp = MIN_EXP;
  23. a.mant= 0;
  24. }
  25. }else{
  26. a.exp= MIN_EXP;
  27. }
  28. return a;
  29. }
  30. static inline SoftFloat av_normalize1_sf(SoftFloat a){
  31. #if 1
  32. if(a.mant + 0x40000000 < 0){
  33. a.exp++;
  34. a.mant>>=1;
  35. }
  36. return a;
  37. #elif 1
  38. int t= a.mant + 0x40000000 < 0;
  39. return (SoftFloat){a.exp+t, a.mant>>t};
  40. #else
  41. int t= (a.mant + 0x40000000U)>>31;
  42. return (SoftFloat){a.exp+t, a.mant>>t};
  43. #endif
  44. }
  45. /**
  46. *
  47. * @return will not be more denormalized then a+b, so if either input is
  48. * normalized then the output wont be worse then the other input
  49. * if both are normalized then the output will be normalized
  50. */
  51. static inline SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){
  52. a.exp += b.exp;
  53. a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS;
  54. return av_normalize1_sf(a);
  55. }
  56. /**
  57. *
  58. * b has to be normalized and not zero
  59. * @return will not be more denormalized then a
  60. */
  61. static SoftFloat av_div_sf(SoftFloat a, SoftFloat b){
  62. a.exp -= b.exp+1;
  63. a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant;
  64. return av_normalize1_sf(a);
  65. }
  66. static inline int av_cmp_sf(SoftFloat a, SoftFloat b){
  67. int t= a.exp - b.exp;
  68. if(t<0) return (a.mant >> (-t)) - b.mant ;
  69. else return a.mant - (b.mant >> t);
  70. }
  71. static inline SoftFloat av_add_sf(SoftFloat a, SoftFloat b){
  72. int t= a.exp - b.exp;
  73. if(t<0) return av_normalize1_sf((SoftFloat){b.exp, b.mant + (a.mant >> (-t))});
  74. else return av_normalize1_sf((SoftFloat){a.exp, a.mant + (b.mant >> t )});
  75. }
  76. static inline SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){
  77. return av_add_sf(a, (SoftFloat){b.exp, -b.mant});
  78. }
  79. //FIXME sqrt, log, exp, pow, sin, cos
  80. static inline SoftFloat av_int2sf(int v, int frac_bits){
  81. return av_normalize_sf((SoftFloat){ONE_BITS-frac_bits, v});
  82. }
  83. /**
  84. *
  85. * rounding is to -inf
  86. */
  87. static inline int av_sf2int(SoftFloat v, int frac_bits){
  88. v.exp += frac_bits - ONE_BITS;
  89. if(v.exp >= 0) return v.mant << v.exp ;
  90. else return v.mant >>(-v.exp);
  91. }