relay 定点乘法(C++)

relay 定点乘法(C++)#

#include <math.h>
#include <utility>
#include <vector>
#include <math.h>
#include <iostream>

double x, y;
int n;
x = 16.4;
y = frexp(x, &n);
std::cout << "std::frexp(x, &n) => " 
         << x << " = " << y << " * "
         << "(1 << " << n << ")";
std::frexp(x, &n) => 16.4 = 0.5125 * (1 << 5)
 0.5125 * (1 << 5)
16.400000
std::pair<int32_t, int32_t> GetFixedPointMultiplierShift(double double_multiplier) {
  int32_t significand, exponent;
  if (double_multiplier == 0.) {
    significand = 0;
    exponent = 0;
    return std::make_pair(significand, exponent);
  }

  // Get the significand and exponent.
  double significand_d = std::frexp(double_multiplier, &exponent);

  // Convert the double significand to int significand, i.e., convert into a
  // integer where the decimal point is between bit 31 and 30. This is done by
  // multiplying the double value with 2^31 and then casting to int.
  significand_d = std::round(significand_d * (1ll << 31));
  auto significand_int64 = static_cast<int64_t>(significand_d);
  ICHECK_LE(significand_int64, (1ll << 31));
  if (significand_int64 == (1ll << 31)) {
    significand_int64 /= 2;
    ++exponent;
  }
  ICHECK_LE(significand_int64, std::numeric_limits<int32_t>::max());
  significand = static_cast<int32_t>(significand_int64);
  return std::make_pair(significand, exponent);
}