Skip to content

Instantly share code, notes, and snippets.

@davidkpiano
Last active February 12, 2022 02:29
Show Gist options
  • Save davidkpiano/ad6e6771df050ff3727f to your computer and use it in GitHub Desktop.
Save davidkpiano/ad6e6771df050ff3727f to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.4.11)
// Compass (v1.0.3)
// ----
@function math-pow($number, $exp) {
@if (round($exp) != $exp) {
@return math-exp($exp * math-ln($number));
}
// Traditional method for integers
$value: 1;
@if $exp > 0 {
@for $i from 1 through $exp {
$value: $value * $number;
}
}
@else if $exp < 0 {
@for $i from 1 through -$exp {
$value: $value / $number;
}
}
@return $value;
}
@function math-factorial($value) {
@if $value == 0 {
@return 1;
}
$result: 1;
@for $index from 1 through $value {
$result: $result * $index;
}
@return $result;
}
@function math-summation($iteratee, $input, $initial: 0, $limit: 100) {
$sum: 0;
@for $index from $initial to $limit {
$sum: $sum + call($iteratee, $input, $index);
}
@return $sum;
}
@function math-exp-maclaurin($x, $n) {
$result: math-pow($x, $n) / math-factorial($n);
@return $result;
}
@function math-exp($value) {
$result: math-summation(math-exp-maclaurin, $value, 0, 100);
@return $result;
}
@function math-ln-maclaurin($x, $n) {
$result: (math-pow(-1, $n + 1) / $n) * (math-pow($x - 1, $n));
@return $result;
}
@function math-ln($value) {
$ten-exp: 1;
$ln-ten: 2.30258509;
@while ($value > math-pow(10, $ten-exp)) {
$ten-exp: $ten-exp + 1;
}
$value: $value / math-pow(10, $ten-exp);
$result: math-summation(math-ln-maclaurin, $value, 1, 100);
@return $result + $ten-exp * $ln-ten;
}
.test {
input: 'math-pow(3, 2)';
expected: 9;
actual: math-pow(3, 2);
input: 'math-pow(4, 3/2)';
expected: 8;
actual: math-pow(4, 3/2);
input: 'math-pow(144, 1/2)';
expected: 12;
actual: math-pow(144, 1/2);
input: 'math-pow(-3, 2)';
expected: 9;
actual: math-pow(-3, 2);
input: 'math-pow(3, -2)';
expected: 0.1111;
actual: math-pow(3, -2);
input: 'math-pow(64, -1/2)';
expected: 0.125;
actual: math-pow(64, -1/2);
input: 'math-pow(12, 3.4)';
expected: 4668.91789313;
actual: math-pow(12, 3.4);
}
.test {
input: 'math-pow(3, 2)';
expected: 9;
actual: 9;
input: 'math-pow(4, 3/2)';
expected: 8;
actual: 8.0;
input: 'math-pow(144, 1/2)';
expected: 12;
actual: 12.0;
input: 'math-pow(-3, 2)';
expected: 9;
actual: 9;
input: 'math-pow(3, -2)';
expected: 0.1111;
actual: 0.11111;
input: 'math-pow(64, -1/2)';
expected: 0.125;
actual: 0.125;
input: 'math-pow(12, 3.4)';
expected: 4668.91789313;
actual: 4668.92127;
}
@xi
Copy link

xi commented Feb 25, 2016

The idea of using taylor/maclaurin expansions is great, but the implementation is very inefficient. For example the implementation of math-pow uses linear time, while it could be implemented in logarithmic time. Also for the series themselves you could save the factorial and power of each step instead of calculating it all again for the next one.

I tried to do a more efficient implementation at http://www.sassmeister.com/gist/5bbe8480c48e2fc10ab5. It compiles about 100 times faster while producing more output (I added sin). What do you think of it?

@jakob-e
Copy link

jakob-e commented Jan 31, 2017

Thank you both :-)
@xi hope you don't mind me linking to your sass-planifolia repo :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment