Skip to content

Commit

Permalink
Add \ and ** operators to the parser
Browse files Browse the repository at this point in the history
Use \ for integer division regardless of the scale, and ** for `BC::pow()`.
  • Loading branch information
danhunsaker committed Feb 24, 2016
1 parent cbf5176 commit 8bdb0ef
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 9 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ your expressions:

- `BC::add(a, b)` => `'a + b'`
- `BC::div(a, b)` => `'a / b'`
- `BC::div(a, b, 0)` => `'a \ b'`
- `BC::mod(a, b)` => `'a % b'`
- `BC::modfrac(a, b)` => `'a %% b'`
- `BC::mul(a, b)` => `'a * b'`
- `BC::pow(a, b)` => `'a ** b'`
- `BC::powfrac(a, b)` => `'a ^ b'`
- `BC::sub(a, b)` => `'a - b'`

Expand Down
8 changes: 6 additions & 2 deletions features/parse.feature
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@ Feature: Parse Method Implementation
| 18 | 1 * 5 | 5.000000000000000000 |
| 0 | 1 / 5 | 0 |
| 18 | 1 / 5 | 0.200000000000000000 |
| 0 | 1 \ 5 | 0 |
| 18 | 1 \ 5 | 0.000000000000000000 |
| 0 | 1 % 5 | 1 |
| 18 | 1 % 5 | 1.000000000000000000 |
| 0 | 5.5 %% 1 | 0 |
| 18 | 5.5 %% 1 | 0.500000000000000000 |
| 0 | 1 ^ .5 | 1 |
| 18 | 1 ^ .5 | 1.000000000000000000 |
| 0 | 4 ** .5 | 1 |
| 18 | 4 ** .5 | 1.000000000000000000 |
| 0 | 4 ^ .5 | 2 |
| 18 | 4 ^ .5 | 2.000000000000000000 |
| 0 | 1 = 5 | false |
| 18 | 1 = 5 | false |
| 0 | 1 == 5 | false |
Expand Down
4 changes: 3 additions & 1 deletion spec/BCSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ public function it_should_have_extended_functionality()

public function it_should_have_utility_functions()
{
$this->scale(18);
$this::scale(18);
$this::parse('1 + 5')->shouldBeLike('6');
$this::parse('1 - 5')->shouldBeLike('-4');
$this::parse('5 \ 4')->shouldBeLike('1');
$this::parse('5 / 4')->shouldBeLike('1.25');
$this::parse('1 + 1.25')->shouldBeLike('2.25');
$this::parse('5 / 4 + 1')->shouldBeLike('2.25');
Expand All @@ -57,6 +58,7 @@ public function it_should_have_utility_functions()
$this::parse('1 + -5 / 4')->shouldBeLike('-0.25');
$this::parse('1 - +5 / 4')->shouldBeLike('-0.25');
$this::parse('(1 + 5) / 4')->shouldBeLike('1.5');
$this::parse('(1 + 5) \ 4')->shouldBeLike('1');
$this::parse('(1 + 5) / 4', null, 0)->shouldBeLike('1');
$this::parse('({a} + {b}) / {c}', ['a' => 1, 'b' => 5, 'c' => 4])->shouldBeLike('1.5');
$this::parse('({a} + {b}) / {c}', ['a' => 1, 'b' => 5, 'c' => 4], 0)->shouldBeLike('1');
Expand Down
14 changes: 8 additions & 6 deletions src/BC.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,11 @@ public static function parse($formula, $values = [], $scale = null)
$formula = preg_replace("/\{[^{}]+\}/", '0', $formula);

$operations = [];
if (strpos($formula, '^') !== false) {
$operations[] = '\^';
if (strpbrk($formula, '^*') !== false) {
$operations[] = '\^|\*\*';
}
if (strpbrk($formula, '*/%') !== false) {
$operations[] = '\*|\/|\%{1,2}';
if (strpbrk($formula, '*/%\\') !== false) {
$operations[] = '\*|\\\\|\/|\%{1,2}';
}
if (strpbrk($formula, '+-') !== false) {
$operations[] = '[\+\-]';
Expand All @@ -243,13 +243,15 @@ public static function parse($formula, $values = [], $scale = null)
case '-': $result = static::sub($opTrio[1], $opTrio[3], $scale); break;
case '*': $result = static::mul($opTrio[1], $opTrio[3], $scale); break;
case '/': $result = static::div($opTrio[1], $opTrio[3], $scale); break;
case '\\': $result = static::div($opTrio[1], $opTrio[3], 0); break;
case '%': $result = static::mod($opTrio[1], $opTrio[3], $scale); break;
case '%%': $result = static::modfrac($opTrio[1], $opTrio[3], $scale); break;
case '**': $result = static::pow($opTrio[1], $opTrio[3], $scale); break;
case '^': $result = static::powfrac($opTrio[1], $opTrio[3], $scale); break;
case '==':
case '=': $result = static::comp($opTrio[1], $opTrio[3], $scale) == 0; break;
case '>': $result = static::comp($opTrio[1], $opTrio[3], $scale) == 1; break;
case '<': $result = static::comp($opTrio[1], $opTrio[3], $scale) ==-1; break;
case '>': $result = static::comp($opTrio[1], $opTrio[3], $scale) > 0; break;
case '<': $result = static::comp($opTrio[1], $opTrio[3], $scale) < 0; break;
case '>=': $result = static::comp($opTrio[1], $opTrio[3], $scale) >= 0; break;
case '<=': $result = static::comp($opTrio[1], $opTrio[3], $scale) <= 0; break;
case '<>':
Expand Down
2 changes: 2 additions & 0 deletions tests/BCTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ public function testParse()
BC::scale(18);
$this->assertEquals('6', BC::parse('1 + 5'));
$this->assertEquals('-4', BC::parse('1 - 5'));
$this->assertEquals('1', BC::parse('5 \ 4'));
$this->assertEquals('1.25', BC::parse('5 / 4'));
$this->assertEquals('2.25', BC::parse('1 + 1.25'));
$this->assertEquals('2.25', BC::parse('5 / 4 + 1'));
Expand All @@ -191,6 +192,7 @@ public function testParse()
$this->assertEquals('-0.25', BC::parse('1 + -5 / 4'));
$this->assertEquals('-0.25', BC::parse('1 - +5 / 4'));
$this->assertEquals('1.5', BC::parse('(1 + 5) / 4'));
$this->assertEquals('1', BC::parse('(1 + 5) \ 4'));
$this->assertEquals('1', BC::parse('(1 + 5) / 4', null, 0));
$this->assertEquals('1.5', BC::parse('({a} + {b}) / {c}', ['a' => 1, 'b' => 5, 'c' => 4]));
$this->assertEquals('1', BC::parse('({a} + {b}) / {c}', ['a' => 1, 'b' => 5, 'c' => 4], 0));
Expand Down

0 comments on commit 8bdb0ef

Please sign in to comment.