Skip to content

Require PHP 8.2 and update the dev tooling - #21

Merged
dereuromark merged 1 commit into
bugfix/edge-casesfrom
php82
Oct 11, 2026
Merged

dereuromark merged 1 commit into
bugfix/edge-casesfrom
php82

Conversation

@dereuromark

Copy link
Copy Markdown
Contributor

Stacked on #20, so the diff only shows the tooling work. Merge that one first.

Raises the PHP requirement from 8.1 to 8.2. PHP 8.1 left security support at the end of 2025. I stopped at 8.2 because dereuromark/cakephp-decimal still supports it, and a higher floor would lock those installs out of new releases, including the fixes in #20. PHP 8.1 users stay on 1.3.

  • PHPUnit ^11.5 || ^12.0 || ^13.0. The 10.x line was only there for 8.1.
  • php-collective/code-sniffer 0.2 to 0.6. The newer rules want attributes imported and docblock types that agree with the native hint, so the operand docblocks now say self like the signatures do.
  • CI matrix is 8.2, 8.3, 8.4 and 8.5 on ubuntu-latest, with coverage on 8.2.
  • The Docker image no longer downloads PHPUnit 10.4 and PHPStan 1.10 phars. The Makefile runs the Composer scripts and never used them.
  • composer.json gains keywords and support.

No runtime behavior changes.

PHP 8.1 has been out of security support since the end of 2025. The
floor stops at 8.2 because dereuromark/cakephp-decimal supports 8.2 and
should keep receiving new releases of this library.

- PHPUnit ^11.5 || ^12 || ^13, the 10.x line was only needed for 8.1.
- php-collective/code-sniffer 0.2 to 0.6. The new rules want attributes
  imported and docblock types that agree with the native hint, so the
  operand docblocks now say self like the signatures do.
- CI runs 8.2, 8.3, 8.4 and 8.5 on ubuntu-latest.
- The Docker image no longer downloads PHPUnit 10.4 and PHPStan 1.10
  phars. The Makefile runs the Composer scripts and never used them.
- composer.json gains keywords and support links.
@dereuromark dereuromark added the enhancement New feature or request label Oct 11, 2026
@codecov

codecov Bot commented Oct 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.68%. Comparing base (d8fc592) to head (fdd6c30).

Additional details and impacted files
@@                 Coverage Diff                  @@
##             bugfix/edge-cases      #21   +/-   ##
====================================================
  Coverage                95.68%   95.68%           
  Complexity                 113      113           
====================================================
  Files                        1        1           
  Lines                      232      232           
====================================================
  Hits                       222      222           
  Misses                      10       10           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dereuromark
dereuromark merged commit a02decd into bugfix/edge-cases Oct 11, 2026
7 checks passed
@dereuromark
dereuromark deleted the php82 branch October 11, 2026 14:31
dereuromark added a commit that referenced this pull request Oct 11, 2026
…es (#20)

* Fix parsing, negative zero, rounding and scientific notation edge cases

Parsing
- Leading zeros survived in several forms: "0010", "-007", "+007" and
  "-00" kept them, and "+.5" lost its leading zero.
- Scientific notation was wrong for any mantissa with more than one
  integer digit and a negative exponent ("12.5e-1" became 0.125,
  "100e-2" became 0.0100) and for mantissas below one with a positive
  exponent (".5e1" became 5.5, "0.00012e3" stayed 0.00012).
- An explicit plus in the exponent ("1e+5") was rejected. PHP renders
  large floats that way, so new Decimal(1e25) threw.
- "1.0e0" dropped the written zero. A trailing ".0" is now only removed
  from the string PHP produces for a float.
- INF and NAN were accepted and stored as the strings "INF" and "NAN".
- A scale of 0 was treated as "no scale": new Decimal('1.5', 0) kept
  the fraction and strict mode did not throw. Negative scales were
  accepted.

Negative zero
- "-0.0", negate() on zero, truncate() and trim() of small negative
  values produced "-0" and reported isNegative() as true while sign()
  returned 0. Zero now never carries a sign.

Rounding
- floor() and ceil() moved whole numbers with a fraction of zeros:
  floor('-1.0') returned -2 and ceil('1.0') returned 2.
- ROUND_FLOOR and ROUND_CEIL ignored the requested scale.
- An unknown round mode silently fell back to half up. It now throws,
  as does a negative scale.

Conversion
- toScientific() returned ".e-1" for zero, went through float division
  and so lost digits beyond 15 for large integers, and returned
  "1.250e2" for 120.50.
- toInt() refused PHP_INT_MIN.

Operands
- mod() and pow() passed the operand to bcmath unparsed, so values in
  scientific notation failed. mod() now defaults to the larger scale of
  both operands, like add(); 10 mod 0.3 returned 0 before.

* Require PHP 8.2 and update the dev tooling (#21)

PHP 8.1 has been out of security support since the end of 2025. The
floor stops at 8.2 because dereuromark/cakephp-decimal supports 8.2 and
should keep receiving new releases of this library.

- PHPUnit ^11.5 || ^12 || ^13, the 10.x line was only needed for 8.1.
- php-collective/code-sniffer 0.2 to 0.6. The new rules want attributes
  imported and docblock types that agree with the native hint, so the
  operand docblocks now say self like the signatures do.
- CI runs 8.2, 8.3, 8.4 and 8.5 on ubuntu-latest.
- The Docker image no longer downloads PHPUnit 10.4 and PHPStan 1.10
  phars. The Makefile runs the Composer scripts and never used them.
- composer.json gains keywords and support links.

* Keep four behavior changes out of 1.x

A run of the old and new class over the same 10,000 calls showed four
of the earlier changes altering results for ordinary input, with no
error to point at the cause. They move to the next major and 1.x keeps
its behavior:

- round() with an unsupported mode rounds half up again, where the fix
  made every such call throw.
- ROUND_FLOOR and ROUND_CEIL round to a whole number whatever scale is
  passed, as the docblock has always said.
- A scale of 0 in the constructor is read as no scale and does not cut
  off decimals.
- mod() defaults to the scale of the value it is called on.

The fixes for wrong results stay: floor() and ceil() on whole numbers
with decimals, operand parsing in mod() and pow(), the negative scale
check.

* Keep three more output changes out of 1.x

Same reasoning as the previous commit, applied to the changes that
only alter the string a caller gets back:

- A string mantissa of "1.0" is read as "1" again, so "1.0e-5" keeps
  a scale of 5.
- Scientific input with a positive exponent and a scale pads the way
  it did before.
- toScientific() keeps the radix mark on a mantissa without decimals
  ("5.e0"). The wrong results stay fixed: zero, lost digits on large
  integers, and values such as 120.50.

All three move to the next major.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant