Blame view

ffmpeg-4.2.2/libavutil/softfloat_ieee754.h 3.61 KB
aac5773f   hucm   功能基本完成,接口待打磨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  /*
   * Copyright (c) 2016 Umair Khan <omerjerk@gmail.com>
   *
   * This file is part of FFmpeg.
   *
   * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
  #ifndef AVUTIL_SOFTFLOAT_IEEE754_H
  #define AVUTIL_SOFTFLOAT_IEEE754_H
  
  #include <stdint.h>
  
  #define EXP_BIAS 127
  #define MANT_BITS 23
  
  typedef struct SoftFloat_IEEE754 {
      int32_t sign;
      uint64_t mant;
      int32_t  exp;
  } SoftFloat_IEEE754;
  
  static const SoftFloat_IEEE754 FLOAT_0 = {0, 0, -126};
  static const SoftFloat_IEEE754 FLOAT_1 = {0, 0,    0};
  
  /** Normalize the softfloat as defined by IEEE 754 single-recision floating
   *  point specification
   */
  static inline SoftFloat_IEEE754 av_normalize_sf_ieee754(SoftFloat_IEEE754 sf) {
      while( sf.mant >= 0x1000000UL ) {
          sf.exp++;
          sf.mant >>= 1;
      }
      sf.mant &= 0x007fffffUL;
      return sf;
  }
  
  /** Convert integer to softfloat.
   *  @return softfloat with value n * 2^e
   */
  static inline SoftFloat_IEEE754 av_int2sf_ieee754(int64_t n, int e) {
      int sign = 0;
  
      if (n < 0) {
          sign = 1;
          n    *= -1;
      }
      return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, n << MANT_BITS, 0 + e});
  }
  
  /** Make a softfloat out of the bitstream. Assumes the bits are in the form as defined
   *  by the IEEE 754 spec.
   */
  static inline SoftFloat_IEEE754 av_bits2sf_ieee754(uint32_t n) {
      return ((SoftFloat_IEEE754) { (n & 0x80000000UL) >> 31, (n & 0x7FFFFFUL), (int8_t)((n & 0x7F800000UL) >> 23)});
  }
  
  /** Convert the softfloat to integer
   */
  static inline int av_sf2int_ieee754(SoftFloat_IEEE754 a) {
      if(a.exp >= 0) return a.mant <<  a.exp ;
      else           return a.mant >>(-a.exp);
  }
  
  /** Divide a by b. b should not be zero.
   *  @return normalized result
   */
  static inline SoftFloat_IEEE754 av_div_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) {
      int32_t mant, exp, sign;
      a    = av_normalize_sf_ieee754(a);
      b    = av_normalize_sf_ieee754(b);
      sign = a.sign ^ b.sign;
      mant = ((((uint64_t) (a.mant | 0x00800000UL)) << MANT_BITS) / (b.mant| 0x00800000UL));
      exp  = a.exp - b.exp;
      return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp});
  }
  
  /** Multiply a with b
   *  #return normalized result
   */
  static inline SoftFloat_IEEE754 av_mul_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) {
      int32_t sign, mant, exp;
      a    = av_normalize_sf_ieee754(a);
      b    = av_normalize_sf_ieee754(b);
      sign = a.sign ^ b.sign;
      mant = (((uint64_t)(a.mant|0x00800000UL) * (uint64_t)(b.mant|0x00800000UL))>>MANT_BITS);
      exp  = a.exp + b.exp;
      return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp});
  }
  
  /** Compare a with b strictly
   *  @returns 1 if the a and b are equal, 0 otherwise.
   */
  static inline int av_cmp_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) {
      a = av_normalize_sf_ieee754(a);
      b = av_normalize_sf_ieee754(b);
      if (a.sign != b.sign) return 0;
      if (a.mant != b.mant) return 0;
      if (a.exp  != b.exp ) return 0;
      return 1;
  }
  
  #endif /*AVUTIL_SOFTFLOAT_IEEE754_H*/