Ticket #8606 (closed defect: fixed)
floats in exponent do not propagate
| Reported by: | zimmerma | Owned by: | zimmerma |
|---|---|---|---|
| Priority: | major | Milestone: | sage-4.4.4 |
| Component: | basic arithmetic | Keywords: | float, RR |
| Cc: | jason, AlexGhitza, was | Work issues: | |
| Report Upstream: | N/A | Reviewers: | Burcin Erocal |
| Authors: | Paul Zimmermann | Merged in: | sage-4.4.4.alpha0 |
| Dependencies: | Stopgaps: |
Description
Consider the following (sage 4.3.3, since 4.3.4 does not compile on my machine):
sage: 2.0^53 9.00719925474099e15
This is what we expect: the float 2.0 propagates to the whole expression.
However:
sage: 2^53.0 9007199254740992
Note the result is an integer, not a float! Thus the information about the inexact value has been lost. Same thing with 2^float(53) and 2^RR(53).
Attachments
Change History
comment:2 Changed 3 years ago by was
The problem is in the function pow in sage/rings/integer.pyx. There we find:
try:
nn = PyNumber_Index(n)
except TypeError:
try:
I think PyNumber?_Index(53.0) is the long "53". Thus to change this as you wish, that code must be changed.
comment:3 Changed 3 years ago by zimmerma
William, in fact nn = PyNumber_Index(n) raises an error, thus we go to
try:
nn = Integer(n)
except TypeError:
try:
s = parent_c(n)(self)
return s**n
where nn = Integer(n) succeeds for n=53.0, but fails for n=53.1:
sage: Integer(53.0) 53 sage: Integer(53.1) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /users/caramel/zimmerma/detached/<ipython console> in <module>() /usr/local/sage-core2/local/lib/python2.6/site-packages/sage/rings/integer.so in sage.rings.integer.Integer.__init__ (sage/rings/integer.c:6449)() /usr/local/sage-core2/local/lib/python2.6/site-packages/sage/rings/real_mpfr.so in sage.rings.real_mpfr.RealNumber._integer_ (sage/rings/real_mpfr.c:11846)() TypeError: Attempt to coerce non-integral RealNumber to Integer
If Integer(53.0) would return an error too, this would fix the problem. However we would then need a specific method to coerce an integral real number to integer...
On a side note, int seems to behave differently:
sage: int(53.0) 53 sage: int(53.1) 53
comment:4 Changed 3 years ago by jason
It seems like we should fix pow, rather than change Integer(53.0). In pow, it seems like we shouldn't just try to blindly coerce to an integer, because that is where we are losing information that we don't want to lose. Why do we have nn = Integer(n)? The previous PyNumber?_Index would take care of cases where we really had an integer power, right? It seems like just deleting the Integer(n) try clause might be the right thing to do.
comment:5 Changed 3 years ago by zimmerma
- Owner changed from AlexGhitza to zimmerma
Jason,
It seems like just deleting the Integer(n) try clause might be the right thing to do.
thanks, that did the trick! I am attaching a patch to review.
comment:8 Changed 3 years ago by zimmerma
- Cc AlexGhitza, was added
Jason, Alex, William, please can anyone of you review this patch? This should be easy. Thanks.
Paul
comment:9 Changed 3 years ago by burcin
- Status changed from needs_review to needs_info
- Reviewers set to Burcin Erocal
The changes in attachment:trac_8606.patch look good to me and all the doctests pass. I'm ready to give this a positive review, but I have a minor comment first:
Shouldn't we also drop the try/except clause around parent_c(n)(self)? The error message returned by the except is not very helpful and I can't think of any test case to actually fall in that clause. Note that if the conversion parent_c(n)(self) fails, we get a TypeError not an AttributeError:
sage: 5^('a')
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'str'
Changed 3 years ago by zimmerma
-
attachment
trac_8606_2.patch
added
apply only this patch (against 4.4.2)
comment:10 follow-up: ↓ 11 Changed 3 years ago by zimmerma
- Status changed from needs_info to needs_review
thank you Burcin for your review. I have attached a new patch following your proposal. However we still get the same (unhelpful) error message for 5^('a'). All doctests still pass.
comment:11 in reply to: ↑ 10 Changed 3 years ago by burcin
- Status changed from needs_review to positive_review
Replying to zimmerma:
thank you Burcin for your review. I have attached a new patch following your proposal. However we still get the same (unhelpful) error message for 5^('a'). All doctests still pass.
I was referring to the message "exponent (=%s) must be an integer.\nCoerce your numbers to real or complex numbers first." as unhelpful. You're right that the message unsupported operand type(s) for ** or pow(): 'str' and 'str' can be confusing as well. It just didn't occur to me since I was staring at the code and expected exactly that.
We could catch the TypeError and change the message to "Cannot find a common domain to perform the operation. Please convert your arguments to the desired types explicitly." or something similar.
I'm still changing this to positive review since the patch fixes a bug and a more meaningful error message is just an enhancement.
comment:12 Changed 3 years ago by mhansen
- Status changed from positive_review to closed
- Resolution set to fixed
- Merged in set to sage-4.4.4.alpha0
