MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / IntegerFrExp

Function IntegerFrExp

tensorflow/lite/kernels/internal/quantization_util.cc:111–175  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

109}
110
111int64_t IntegerFrExp(double input, int* shift) {
112 // Make sure our assumptions about the double layout hold.
113 TFLITE_CHECK_EQ(8, sizeof(double));
114
115 // We want to access the bits of the input double value directly, which is
116 // tricky to do safely, so use a union to handle the casting.
117 union {
118 double double_value;
119 uint64_t double_as_uint;
120 } cast_union;
121 cast_union.double_value = input;
122 const uint64_t u = cast_union.double_as_uint;
123
124 // If the bitfield is all zeros apart from the sign bit, this is a normalized
125 // zero value, so return standard values for this special case.
126 if ((u & ~kSignMask) == 0) {
127 *shift = 0;
128 return 0;
129 }
130
131 // Deal with NaNs and Infs, which are always indicated with a fixed pattern in
132 // the exponent, and distinguished by whether the fractions are zero or
133 // non-zero.
134 const uint32_t exponent_part = ((u & kExponentMask) >> kExponentShift);
135 if (exponent_part == kExponentIsBadNum) {
136 *shift = std::numeric_limits<int>::max();
137 if (u & kFractionMask) {
138 // NaN, so just return zero (with the exponent set to INT_MAX).
139 return 0;
140 } else {
141 // Infinity, so return +/- INT_MAX.
142 if (u & kSignMask) {
143 return std::numeric_limits<int64_t>::min();
144 } else {
145 return std::numeric_limits<int64_t>::max();
146 }
147 }
148 }
149
150 // The shift is fairly easy to extract from the high bits of the double value,
151 // just by masking it out and applying a bias. The std::frexp() implementation
152 // always returns values between 0.5 and 1.0 though, whereas the exponent
153 // assumes 1.0 to 2.0 is the standard range, so I add on one to match that
154 // interface.
155 *shift = (exponent_part - kExponentBias) + 1;
156
157 // There's an implicit high bit in the double format definition, so make sure
158 // we include that at the top, and then reconstruct the rest of the fractional
159 // value from the remaining fragments.
160 int64_t fraction = 0x40000000 + ((u & kFractionMask) >> kFractionShift);
161
162 // We're cutting off some bits at the bottom, so to exactly match the standard
163 // frexp implementation here we'll apply rounding by adding one to the least
164 // significant bit of the result if the discarded portion is over half of the
165 // maximum.
166 if ((u & kFractionRoundingMask) > kFractionRoundingThreshold) {
167 fraction += 1;
168 }

Callers 5

TESTFunction · 0.85
QuantizeMultiplierFunction · 0.85
IntegerDoubleMultiplyFunction · 0.85
IntegerDoubleCompareFunction · 0.85
PreprocessSoftmaxScalingFunction · 0.85

Calls 2

maxFunction · 0.50
minFunction · 0.50

Tested by 1

TESTFunction · 0.68