Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to ROUNDDOWN/ROUNDUP/TRUNC #4214

Merged
merged 3 commits into from
Nov 6, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Option to Write Hyperlink Rather Than Label to Csv. [Issue #1412](https://github.com/PHPOffice/PhpSpreadsheet/issues/1412) [PR #4151](https://github.com/PHPOffice/PhpSpreadsheet/pull/4151)
- Invalid Html Due to Cached Filesize. [Issue #1107](https://github.com/PHPOffice/PhpSpreadsheet/issues/1107) [PR #4184](https://github.com/PHPOffice/PhpSpreadsheet/pull/4184)
- Excel 2003 Allows Html Entities. [Issue #2157](https://github.com/PHPOffice/PhpSpreadsheet/issues/2157) [PR #4187](https://github.com/PHPOffice/PhpSpreadsheet/pull/4187)
- Changes to ROUNDDOWN/ROUNDUP/TRUNC. [Issue #4213](https://github.com/PHPOffice/PhpSpreadsheet/issues/4213) [PR #4214](https://github.com/PHPOffice/PhpSpreadsheet/pull/4214)
- Writer Xlsx ignoredErrors Before Drawings. [Issue #4200](https://github.com/PHPOffice/PhpSpreadsheet/issues/4200) [Issue #4145](https://github.com/PHPOffice/PhpSpreadsheet/issues/4145) [PR #4212](https://github.com/PHPOffice/PhpSpreadsheet/pull/4212)
- Allow ANCHORARRAY as Data Validation list. [Issue #4197](https://github.com/PHPOffice/PhpSpreadsheet/issues/4197) [PR #4203](https://github.com/PHPOffice/PhpSpreadsheet/pull/4203)

Expand Down
49 changes: 22 additions & 27 deletions src/PhpSpreadsheet/Calculation/MathTrig/Round.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
// following added in Php8.4
use RoundingMode;

class Round
{
Expand Down Expand Up @@ -67,31 +69,28 @@ public static function up($number, $digits): array|string|float
return 0.0;
}

$digitsPlus1 = $digits + 1;
if ($number < 0.0) {
if ($digitsPlus1 < 0) {
return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN);
}
$result = sprintf("%.{$digitsPlus1}F", $number - 0.5 * 0.1 ** $digits);

return round((float) $result, $digits, PHP_ROUND_HALF_DOWN);
if (PHP_VERSION_ID >= 80400) {
return round(
(float) (string) $number,
$digits,
RoundingMode::AwayFromZero //* @phpstan-ignore-line
);
}

if ($digitsPlus1 < 0) {
return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN);
if ($number < 0.0) {
return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN);
}
$result = sprintf("%.{$digitsPlus1}F", $number + 0.5 * 0.1 ** $digits);

return round((float) $result, $digits, PHP_ROUND_HALF_DOWN);
return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN);
}

/**
* ROUNDDOWN.
*
* Rounds a number down to a specified number of decimal places
*
* @param array|float $number Number to round, or can be an array of numbers
* @param array|int $digits Number of digits to which you want to round $number, or can be an array of numbers
* @param null|array|float|string $number Number to round, or can be an array of numbers
* @param array|float|int|string $digits Number of digits to which you want to round $number, or can be an array of numbers
*
* @return array|float|string Rounded Number, or a string containing an error
* If an array of numbers is passed as the argument, then the returned result will also be an array
Expand All @@ -114,23 +113,19 @@ public static function down($number, $digits): array|string|float
return 0.0;
}

$digitsPlus1 = $digits + 1;
if ($number < 0.0) {
if ($digitsPlus1 < 0) {
return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP);
}
$result = sprintf("%.{$digitsPlus1}F", $number + 0.5 * 0.1 ** $digits);

return round((float) $result, $digits, PHP_ROUND_HALF_UP);
if (PHP_VERSION_ID >= 80400) {
return round(
(float) (string) $number,
$digits,
RoundingMode::TowardsZero //* @phpstan-ignore-line
);
}

if ($digitsPlus1 < 0) {
return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP);
if ($number < 0.0) {
return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP);
}

$result = sprintf("%.{$digitsPlus1}F", $number - 0.5 * 0.1 ** $digits);

return round((float) $result, $digits, PHP_ROUND_HALF_UP);
return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP);
}

/**
Expand Down
37 changes: 4 additions & 33 deletions src/PhpSpreadsheet/Calculation/MathTrig/Trunc.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;

use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
use PhpOffice\PhpSpreadsheet\Calculation\Exception;

class Trunc
{
Expand All @@ -19,47 +18,19 @@ class Trunc
* (or possibly that value minus 1).
* Excel is unlikely to do any better.
*
* @param array|float $value Or can be an array of values
* @param array|int $digits Or can be an array of values
* @param null|array|float|string $value Or can be an array of values
* @param array|float|int|string $digits Or can be an array of values
*
* @return array|float|string Truncated value, or a string containing an error
* If an array of numbers is passed as an argument, then the returned result will also be an array
* with the same dimensions
*/
public static function evaluate(array|float|string|null $value = 0, array|int|string $digits = 0): array|float|string
public static function evaluate(array|float|string|null $value = 0, array|float|int|string $digits = 0): array|float|string
{
if (is_array($value) || is_array($digits)) {
return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $digits);
}

try {
$value = Helpers::validateNumericNullBool($value);
$digits = Helpers::validateNumericNullSubstitution($digits, null);
} catch (Exception $e) {
return $e->getMessage();
}

if ($value == 0) {
return $value;
}

if ($value >= 0) {
$minusSign = '';
} else {
$minusSign = '-';
$value = -$value;
}
$digits = (int) floor($digits);
if ($digits < 0) {
$result = (float) (substr(sprintf('%.0F', $value), 0, $digits) . str_repeat('0', -$digits));

return ($minusSign === '') ? $result : -$result;
}
$decimals = (floor($value) == (int) $value) ? (PHP_FLOAT_DIG - strlen((string) (int) $value)) : $digits;
$resultString = ($decimals < 0) ? sprintf('%F', $value) : sprintf('%.' . $decimals . 'F', $value);
$regExp = '/([.]\\d{' . $digits . '})\\d+$/';
$result = $minusSign . (preg_replace($regExp, '$1', $resultString) ?? $resultString);

return (float) $result;
return Round::down($value, $digits);
}
}
4 changes: 3 additions & 1 deletion tests/data/Calculation/MathTrig/ROUNDDOWN.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@
[0, 'B1, 0'],
['exception', ''],
['exception', '35.51'],
'negative number and precision' => [-31400, '-31415.92654, -2'],
'negative number and precision ROUNDDOWN' => [-31400, '-31415.92654, -2'],
'issue 4213 #1' => [249.0, '249.9975, 0'],
'issue 4213 #2' => [-249.0, '-249.9975, 0'],
];
2 changes: 2 additions & 0 deletions tests/data/Calculation/MathTrig/ROUNDUP.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@
['exception', ''],
['exception', '35.51'],
'negative number and precision' => [-31500, '-31415.92654, -2'],
'issue 4213 #1' => [250.0, '249.9975, 0'],
'issue 4213 #2' => [-250.0, '-249.9975, 0'],
];
Loading