-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
pi < pi
gives error
#8411
Comments
There is quite a cottage industry of filing issues about |
Another open question is whether |
A weirder thing is this: julia> pi == pi
true
julia> pi <= pi
ERROR: stack overflow
in <= at promotion.jl:170 (repeats 79996 times) |
I don't think it's going to be reasonable to do general operations with math consts. We should certainly make the error messages better but there's just no end to this and there's no good reason to want to do any of this. |
There's no reason to want to do any of this intentionally, but library code and user code could certainly come together to cause some unintended interactions of this kind. MathConst seems like it has something in common with C++14 variable templates. What behavior does that specify, and is it possible to emulate if that makes sense? |
I imagine that this can happen in the rare case that some function is defined like
then
|
Is there any issue about adding
to Base? |
No, that seems ok. Then the next question becomes how to compare different MathConsts – assuming that they differ as Float64s seems viable. What about comparing Float64 and MathConst? How would one do that? Widen the Float64 to BigFloat and then compare? What about comparing a BigFloat and a MathConst? |
One idea is defining nextfloat and prevfloat for MathConst where the exact value is between those two. You would need a type argument, of course. |
@cdsousa's suggestion seems to work fine for the c = MathConst[π, e, γ, catalan, φ]
for x in c, y in c, ∘ in [<, ≤, == ,> ,≥ ]
fx, fy = float(x), float(y)
@assert (x ∘ y) == (fx ∘ fy)
end |
Mixing for x in c, y in c, ∘ in [<, ≤, == ,> ,≥ ]
fx, fy = float(x), float(y)
@assert (x ∘ y) == (fx ∘ fy) == (x ∘ fy) == (fx ∘ y)
end |
The issue of comparing |
MathConsts are generally irrational whereas Rationals aren't. Then again, overflow is less of an issue. There are many problems with the current state of affairs: julia> pi == float(pi)
true
julia> pi == big(pi)
true
julia> float(pi) == big(pi)
false
julia> float(pi) < pi
false
julia> float(pi) < big(pi)
true I'm starting to think we should have just gone with making |
The float-to-big comparisons make sense--you're clearly working with different quantities there. In the perspective that MathConst is like a templated variable, the other three also make sense, since the MathConst just takes whichever type is inferred. So I'm not sure what's wrong with any of the six examples you've posed. |
The first three results show that |
Here's a fun example with the current comparison behavior: julia> float(e) < big(e)
true
julia> float(e) <= e <= big(e)
true
julia> float(e) < e
false
julia> e < big(e)
false |
But that assumes that I would accept lack of transparency as to which representation you're going to get is a fair critique--we call them MathConsts, but they're not mathy things. |
If they're not single values then all of these operations should be errors. |
And this is why I brought up C++14 variable templates. I'd be interested how many of these kinds of expressions are compilation errors, and how many get inferred instantiations in that environment. |
I don't know anything about C++14 variable templates so that particular reference was entirely lost on me. The thing is we can make all of these thing behave sensibly, it's just a question of how. |
A |
When comparing a float with a Then the same principle could be applied when comparing |
Here's my proposal for handling comparisons:
A quick explanation:
The only one that that this doesn't cover is |
@simonbyrne: That looks like a really good proposal (and impressively comprehensive). @nalimilan: Floating-point numbers aren't intervals – they have precise rational values. The fact that 0.00000000000000001 and 0.00000000000000002 are two different input forms for the same |
The I like the |
Sorry, @dpsanders, I didn't mean to imply that you were doing anything stupid. It's just a question of how far down this rabbit hole we want to go. Do we throw an error message when this happens and force the user to pick a type for |
It might be worth considering how FixedPointNumbers.jl and Nemo/Flint fit in with any scheme used for inter-type comparisons. Of course, details would probably have to be taken care of in the packages themselves, but how easy would it be? |
Does anyone have any suggestions for implementing prevfloat(x::MathConst) = with_rounding(()->float64(big(x)),BigFloat,RoundDown)
nextfloat(x::MathConst) = with_rounding(()->float64(big(x)),BigFloat,RoundUp) but it doesn't make sense to make it a function call, as the answer will always be constant. However we can't farm it out to the |
Staged functions seem like they would help with this. |
This should now be fixed. |
This seems to me to be a bug.
It can be fixed as follows, but this does not seem like a very good idea:
The text was updated successfully, but these errors were encountered: