library MathFixed {

  /**
  * @dev Multiplies two fixed_point numbers.
  */
  function mulFixed(uint256 a, uint256 b) internal pure returns (uint256) {
    return (((a * b) >> 95) + 1) >> 1;
  }

  /**
  * @dev return a^n with fixed_point a, unsinged integer n.
  * using exponentiation_by_squaring
  */
  function powFixed(uint256 a, uint256 n) internal pure returns (uint256){
    uint256 r = 79228162514264337593543950336; // 1.0  * 2^96
    while(n > 0){
      if(n&1 > 0){
        r = mulFixed(a, r);
      }
      a = mulFixed(a, a);
      n >>= 1;
    }
    return r;
  }
}
function powFixed(uint256 a, uint256 n) internal pure returns (uint256){
  uint256 r = 79228162514264337593543950336; // 1.0  * 2^96
  while(n > 0){
    if(n&1 > 0){
      r = mulFixed(a, r);
    }
    a = mulFixed(a, a);
    n >>= 1;
  }
  return r;
}

/**
 * @dev return a^n with fixed_point a, unsinged integer n.
 * using exponentiation_by_squaring
 */