-
Notifications
You must be signed in to change notification settings - Fork 67
Floats are equal, but their hash is different #513
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
Comments
The SymEngine Float is not the same as Python float. Two different objects and Python uses a different hash functions to calculate its hash. |
I know, but if two objects equate, they should also yield the same hash, otherwise you get undefined behavior in e.g. hash tables |
I think @Darkdragon84 is right, it is not immediately obvious to me how we would achieve this, but poking around with some python standard library classes, this promise seems to hold: >>> import decimal
>>> decimal.Decimal('0.5') == 0.5
True
>>> hash(decimal.Decimal('0.5')) == hash(0.5)
True
>>> from fractions import Fraction
>>> Fraction(1, 2) == 0.5
True
>>> hash(Fraction(1, 2)) == hash(0.5)
True If we support EDIT:
|
We need to be careful to not create a strong coupling to the Python hash implementation. So if this should be fixed it needs to be in the Python bindings. Other languages we want to bind to most probably does the hashing in a different way. I feel that the only way would be to first convert to a Python |
@rikardn I agree, any overhead should solely be carried by the python bindings, and if there is any overhead I think we should make it simple to opt-out of at compile time (or runtime, if that's doable). Converting to Regarding >>> symengine.Rational(1,2) == 0.5
False (but that would be a separate issue I guess). |
@bjodah The float not comparing equal to a rational is by design. We see 1/2 as an exact number and 0.5 being 0.5 + |
I know, and that's fine. But I still would have preferred it comparing
equal whenever the floating point representation matches exactly.
…On Wed, Apr 9, 2025, 08:17 Rikard Nordgren ***@***.***> wrote:
@bjodah <https://github.com/bjodah> The float not comparing equal to a
rational is by design. We see 1/2 as an exact number and 0.5 being 0.5 +
$\epsilon$, where espilon can be a small irrational number.
—
Reply to this email directly, view it on GitHub
<#513 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADWUMFKBNPOXWVLWUAYF3L2YS3QBAVCNFSM6AAAAAB2OR3PYSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOOBYGM4DSNBYHA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
*rikardn* left a comment (symengine/symengine.py#513)
<#513 (comment)>
@bjodah <https://github.com/bjodah> The float not comparing equal to a
rational is by design. We see 1/2 as an exact number and 0.5 being 0.5 +
$\epsilon$, where espilon can be a small irrational number.
—
Reply to this email directly, view it on GitHub
<#513 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADWUMFKBNPOXWVLWUAYF3L2YS3QBAVCNFSM6AAAAAB2OR3PYSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOOBYGM4DSNBYHA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
It generally holds that if two hashable objects are equal, their hashes must be the same.
It seems that python builtin
float
andsymengine.Float
violate this rule:Shouldn't the hash of a
symengine.Float
just use the pythonfloat
's hash?The text was updated successfully, but these errors were encountered: