Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/reference/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ See [Creating decimals](../guide/creating).
| `multiply($value, ?int $scale = null): static` | Product | sum of both |
| `divide($value, int $scale, ?int $roundMode = null): static` | Quotient, cut off at `$scale`, or rounded when a mode is given | required |
| `divideWithRemainder($value): array` | Whole number quotient and remainder | 0, and larger of both |
| `mod($value, ?int $scale = null): static` | Remainder. `$value` is a `Decimal`, string or integer. | scale of the value |
| `pow($exponent, ?int $scale = null): static` | Power. `$exponent` is a whole number as `Decimal`, string or integer. | scale of the value |
| `mod($value, ?int $scale = null): static` | Remainder | scale of the value |
| `pow($exponent, ?int $scale = null): static` | Power. `$exponent` is a whole number. | scale of the value |
| `sqrt(?int $scale = null): static` | Square root | scale of the value |
| `shift(int $places): static` | Moves the decimal point, multiplying by a power of ten | follows the digits |
| `absolute(): static` | Value without sign | unchanged |
Expand Down
8 changes: 4 additions & 4 deletions src/Decimal.php
Original file line number Diff line number Diff line change
Expand Up @@ -775,12 +775,12 @@ protected function fractionalLength(): int
/**
* This method is equivalent to the ** operator.
*
* @param self|string|int $exponent
* @param self|string|float|int $exponent
* @param int|null $scale Decimal places in the result. Omit to enable auto-detection.
*
* @return static
*/
public function pow(self|string|int $exponent, ?int $scale = null): static
public function pow(self|string|float|int $exponent, ?int $scale = null): static
{
if ($scale === null) {
$scale = $this->scale();
Expand Down Expand Up @@ -808,12 +808,12 @@ public function sqrt(?int $scale = null): static
/**
* This method is equivalent to the % operator.
*
* @param self|string|int $value
* @param self|string|float|int $value
* @param int|null $scale Decimal places in the result. Omit to enable auto-detection.
*
* @return static
*/
public function mod(self|string|int $value, ?int $scale = null): static
public function mod(self|string|float|int $value, ?int $scale = null): static
{
if ($scale === null) {
$scale = $this->scale();
Expand Down
42 changes: 42 additions & 0 deletions tests/DecimalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use PHPUnit\Framework\TestCase;
use Stringable;
use TypeError;
use ValueError;

class DecimalTest extends TestCase
{
Expand Down Expand Up @@ -1981,4 +1982,45 @@ public function testAllocateWithZeroScaleDeclared(): void

$this->assertSame(['0.8', '0.7'], array_map('strval', $shares));
}

/**
* Without `float` in the parameter type PHP turns 2.5 into 2 for callers not using strict types.
*
* @return void
*/
public function testModFloatOperand(): void
{
$this->assertSame('2.0', (string)(new Decimal('7'))->mod(2.5, 1));
$this->assertSame('2.0', (string)(new Decimal('7.0'))->mod(2.5));
$this->assertSame('1', (string)(new Decimal('7'))->mod(2.0));
}

/**
* @return void
*/
public function testPowFloatOperand(): void
{
$this->assertSame('16', (string)(new Decimal('4'))->pow(2.0));
}

/**
* @return void
*/
public function testPowFractionalFloatOperand(): void
{
$this->expectException(ValueError::class);

(new Decimal('4'))->pow(0.5);
}

/**
* @return void
*/
public function testFloatOperandsAreNotTruncatedWithoutStrictTypes(): void
{
$result = require __DIR__ . '/data/float_operands.php';

$this->assertSame('2.0', $result['mod']);
$this->assertSame(ValueError::class, $result['pow']);
}
}
20 changes: 20 additions & 0 deletions tests/data/float_operands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/**
* MIT License
* For full license information, please view the LICENSE file that was distributed with this source code.
*/

// No strict_types on purpose: this is how a caller without it reaches the methods.

use PhpCollective\DecimalObject\Decimal;

$result = ['mod' => (string)(new Decimal('7.0'))->mod(2.5)];

try {
$result['pow'] = (string)(new Decimal('4'))->pow(0.5);
} catch (Throwable $e) {
$result['pow'] = $e::class;
}

return $result;
Loading