-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] Add NumberNormalizer
#59670
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
Conversation
43e9064
to
6e56489
Compare
@valtzu Thank you for the PR. I agree that the purpose of using BcMath\Number is precision. However, the input could very well be a float considering it can come from any source (api response, db result, etc), and while operating on floats directly is risky due to precision loss, converting them into a numeric string (or a Number object) preserves accuracy. This aligns with the goal of using BCMath in the first place. As far normalizing into int or string, I think normalizing into string seems a sensible default but maybe we can optionally have a flag (which can be provided via context) to output as int. I am fine with numeric-string though. |
Regarding API responses: Unfortunately, it's a limitation of the two-step process of decoding and denormalization that we convert a JSON number to a PHP float first. If we're dealing with JSON numbers, this normalizer is probably not what we want. Regarding DB results: In SQL, you would represent a number as
No. The moment you cast a value to a float, you risk losing precision. Converting them to a string won't recover the precsion you lost. I'm fine with the normalizer in its current state. |
It is quite normal to use symfony serializer to convert incoming api requests into dtos, numbers are often represented using floats in api requests. Things like MapRequestPayload, etc will work ootb.
Yes, pdo does it alright, so probably not an issue.
Well, nobody is casting a number into a float, the numbers can be float initially (say from an api request), float needs to be converted into a string or BcMath\Number to ensure that operations are done with precision, if the denormalizer can accept float too it will save the additional cast. |
src/Symfony/Component/Serializer/Tests/Normalizer/NumberNormalizerTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Tests/Normalizer/NumberNormalizerTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Tests/Normalizer/NumberNormalizerTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Tests/Normalizer/NumberNormalizerTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Normalizer/NumberNormalizer.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Normalizer/NumberNormalizer.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Normalizer/NumberNormalizer.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Normalizer/NumberNormalizer.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Tests/Normalizer/NumberNormalizerTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Tests/Normalizer/NumberNormalizerTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Tests/Normalizer/NumberNormalizerTest.php
Outdated
Show resolved
Hide resolved
95da9ee
to
e71ba33
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
src/Symfony/Component/Serializer/Normalizer/NumberNormalizer.php
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With minor comments.
Great work 🙂
src/Symfony/Component/Serializer/Tests/Normalizer/NumberNormalizerTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Tests/Normalizer/NumberNormalizerTest.php
Outdated
Show resolved
Hide resolved
449dcbd
to
1801c74
Compare
1801c74
to
7d3be64
Compare
What about supporting GMP numbers also? Could be done in the same PR, even maybe same class? |
7d3be64
to
22a9066
Compare
Ok, done. |
22a9066
to
d3e3dfe
Compare
|
||
/** | ||
* @requires PHP 8.4 | ||
* @requires extension bcmath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that we need either bcmath and gmp, I think this should be separated
Thank you @valtzu. |
…ension (xabbuh) This PR was merged into the 7.3 branch. Discussion ---------- [Serializer] separate NumberNormalizer tests per PHP extension | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | no | Deprecations? | no | Issues | Fix #59670 (comment) | License | MIT Commits ------- efe1e94 separate NumberNormalizer tests per PHP extension
Normalize
BcMath\Number
tostring
.A few changes in comparison to the original issue description:
float
s not supported at all. No point using precision math if you start with non-precise value.Number
is always normalized to astring
. If we wanted theint
cast, it should be opt-in with some context key likecast_zero_scale_to_int
– though I personally don't see a need for it.