Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 2.7.1 under development

- no changes in this release.
- New #156: Add `NumericHelper::trimDecimalZeros()` (@samdark)

## 2.7.0 November 23, 2025

Expand Down
29 changes: 28 additions & 1 deletion src/NumericHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
}

/**
* Converts human readable size to bytes.
* Converts human-readable size to bytes.
*
* @param string $string Human readable size. Examples: `1024`, `1kB`, `1.5M`, `1GiB`. Full
* list of supported postfixes in {@see FILESYSTEM_SIZE_POSTFIXES}.
Expand Down Expand Up @@ -157,9 +157,36 @@
throw new InvalidArgumentException("Not supported postfix '$postfix' in input string: $string");
}

return (int) ((float) $numericPart * $postfixMultiplier);

Check warning on line 160 in src/NumericHelper.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.5-ubuntu-latest

Escaped Mutant for Mutator "CastFloat": @@ @@ if ($postfixMultiplier === null) { throw new InvalidArgumentException("Not supported postfix '{$postfix}' in input string: {$string}"); } - return (int) ((float) $numericPart * $postfixMultiplier); + return (int) ($numericPart * $postfixMultiplier); } throw new InvalidArgumentException("Incorrect input string: {$string}"); }
}

throw new InvalidArgumentException("Incorrect input string: $string");
}

/**
* Trims trailing decimal zeros from a numeric-like string.
*
* If the fractional part consists only of zeros, the decimal separator is removed as well.
* The value that is `null` or empty is returned as-is.
*
* @param string|null $value String representation of a number or any string potentially
* containing a decimal part.
*
* @return string|null The input string with trailing decimal zeros (and a trailing decimal
* separator, if any) removed, or `null` if the input was `null`.
*/
public static function trimDecimalZeros(?string $value): ?string
{
if ($value === null || !str_contains($value, '.')) {
return $value;
}
/** @psalm-suppress PossiblyNullArgument */
$value = rtrim($value, '0');

if ($value === '' || !str_ends_with($value, '.')) {
return $value;
}

return substr($value, 0, -1);
}
}
24 changes: 24 additions & 0 deletions tests/NumericHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,28 @@ public function testConvertHumanReadableSizeToBytesWithInvalidStrings(string $st
$this->expectExceptionObject(new \InvalidArgumentException($message));
NumericHelper::convertHumanReadableSizeToBytes($string);
}

public static function decimalZerosProvider(): array
{
return [
'no decimals in integer with zeros' => ['390', '390'],
'all zeros' => ['390.000', '390'],
'no zeros' => ['3.14', '3.14'],
'some zeros' => ['42.010', '42.01'],
'null' => [null, null],
'zeros' => ['0.0', '0'],
'empty' => ['', ''],
'decimal only' => ['.5', '.5'],
'start with zero' => ['0.25', '0.25'],
'negative' => ['-3.000', '-3'],
];
}

/**
* @dataProvider decimalZerosProvider
*/
public function testTrimDecimalZeros(?string $input, ?string $expected): void
{
$this->assertSame($expected, NumericHelper::trimDecimalZeros($input));
}
}
Loading