/// # MathSass Functions
///
/// *We borrowed this set of math constants and functions
/// from Takeru Suzuki's wonderful [MathSass][MathSass] library.
/// See the full MIT License below…*
///
/// [MathSass]: https://github.com/terkel/mathsass/
/// @access private


// Constants
// ---------
$_LN2: 0.6931471805599453; // sass-lint:disable-line variable-name-format
$_SQRT2: 1.4142135623730951; // sass-lint:disable-line variable-name-format


/// Returns base to the exponent power.
///
/// @access private
///
/// @param {Number} $base –
///   The base number
/// @param {Number} $exp -
///   The exponent to which to raise base
/// @return {Number}
/// @example scss
///   /* #{ _acc-pow(4, 2)   } */
///   /* #{ _acc-pow(4, -2)  } */
///   /* #{ _acc-pow(4, 0.2) } */
@function _acc-pow(
  $base,
  $exp
) {
  @if $exp == floor($exp) {
    $r: 1;
    $s: 0;
    @if $exp < 0 {
      $exp: $exp * -1;
      $s: 1;
    }
    @while $exp > 0 {
      @if $exp % 2 == 1 {
        $r: $r * $base;
      }
      $exp: floor($exp * 0.5);
      $base: $base * $base;
    }
    @return if($s != 0, 1 / $r, $r);
  } @else if $base == 0 and $exp > 0 {
    @return 0;
  } @else {
    $expint: floor($exp);
    $r1: _acc-pow($base, $expint);
    $r2: _exp(_acc-log($base) * ($exp - $expint));
    @return $r1 * $r2;
  }
}


/// A good approximation for $x close to 0.
/// @access private
@function _exp(
  $x
) {
  $ret: 0;
  $i: 1;
  @for $n from 0 to 24 {
    $ret: $ret + $i;
    $i: $i * $x / ($n + 1);
  }
  @return $ret;
}


/// Returns the natural logarithm of a number.
///
/// @access private
///
/// @param {Number} $x
/// @param {Number} $b The base number
/// @example scss
///   /* #{ _acc-log(2)     } */
///   /* #{ _acc-log(10)    } */
///   /* #{ _acc-log(2, 10) } */
@function _acc-log(
  $x,
  $b: null
) {
  @if $b != null {
    @return _acc-log($x) / _acc-log($b);
  }

  @if $x <= 0 {
    @return 0 / 0;
  }
  $k: nth(_acc-frexp($x / $_SQRT2), 2); // sass-lint:disable-line variable-name-format
  $x: $x / _acc-ldexp(1, $k);

  @return $_LN2 * $k + _acc-log-approx($x); // sass-lint:disable-line variable-name-format
}


/// a good aproximation for $x close to 1
/// @access private
@function _acc-log-approx(
  $x
) {
  $x: ($x - 1) / ($x + 1);
  $x2: $x * $x;
  $i: 1;
  $s: $x;
  $sp: null;
  @while $sp != $s {
    $x: $x * $x2;
    $i: $i + 2;
    $sp: $s;
    $s: $s + $x / $i;
  }
  @return 2 * $s;
}


/// Returns a two-element list
/// containing the normalized fraction and exponent of number.
///
/// @access private
///
/// @param {Number} $x
/// @return {List} fraction, exponent
@function _acc-frexp(
  $x
) {
  $exp: 0;
  @if $x < 0 {
    $x: $x * -1;
  }
  @if $x < 0.5 {
    @while $x < 0.5 {
      $x: $x * 2;
      $exp: $exp - 1;
    }
  } @else if $x >= 1 {
    @while $x >= 1 {
      $x: $x / 2;
      $exp: $exp + 1;
    }
  }
  @return $x, $exp;
}


// Returns $x * 2^$exp
///
/// @access private
///
/// @param {Number} $x
/// @param {Number} $exp
@function _acc-ldexp(
  $x,
  $exp
) {
  $b: if($exp >= 0, 2, 1 / 2);
  @if $exp < 0 {
    $exp: $exp * -1;
  }
  @while $exp > 0 {
    @if $exp % 2 == 1 {
      $x: $x * $b;
    }
    $b: $b * $b;
    $exp: floor($exp * 0.5);
  }
  @return $x;
}


/// ## [Copyright (C) 2013 Takeru Suzuki][MathSass]
///
/// Permission is hereby granted, free of charge,
/// to any person obtaining a copy of this software
/// and associated documentation files (the "Software"),
/// to deal in the Software without restriction,
/// including without limitation the rights to use,
/// copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software,
/// and to permit persons to whom the Software is furnished to do so,
/// subject to the following conditions:
///
/// The above copyright notice and this permission notice
/// shall be included in all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
/// THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
/// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
/// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE
/// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///
/// [MathSass]: https://github.com/terkel/mathsass/
/// @access private
