Opened 11 years ago

Closed 9 years ago

#9627 closed defect (duplicate)

converting from symbolic ring to int is broken

Reported by: syazdani Owned by: robertwb
Priority: major Milestone: sage-duplicate/invalid/wontfix
Component: symbolics Keywords:
Cc: katestange, mjo Merged in:
Authors: Reviewers: Burcin Erocal
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Status badges


Here is simple example:

sage: h = 3^64;
sage: int(h)==int(SR(h))

Looking a bit deeper into this, it seems that the first 100 bits are correct, and after that int(SR(h)) is just zeroes. (As a side note, the conversion to ZZ works without a problem.)

Change History (9)

comment:1 Changed 11 years ago by tornaria

  • Status changed from new to needs_work


    def __int__(self):
            sage: int(sin(2)*100)
            sage: int(log(8)/log(2))
        #FIXME: can we do better?
        return int(self.n(prec=100))

Can we just change that to

        return int(self._integer_())


comment:2 Changed 11 years ago by tornaria

  • Component changed from coercion to symbolics


sage: ZZ(log(8)/log(2))
TypeError: unable to convert x (=log(8)/log(2)) to an integer


sage: int(log(8)/log(2))  

OTOH, int(sin(2)*100) is not equal to 90... not an integer anyway... What's the expected meaning of int(x)?

comment:3 Changed 11 years ago by cwitty

Pure Python implements int() of a float as truncating toward zero:

>>> int(3.14159)
>>> int(-3.14159)
>>> int(2.71828)
>>> int(-2.71828)

I think in general we've implemented int() on real numbers of various types as truncating toward zero to follow this precedent.

comment:4 Changed 11 years ago by tornaria

Something like this may work:

def SR_int(x):
    sage: SR_int(sin(2)*100)
    sage: SR_int(-sin(2)*100)
    sage: SR_int(log(8)/log(2))
    sage: SR_int(-log(8)/log(2))
    sage: SR_int(SR(3^64)) == 3^64
    sage: SR_int(SR(10^100)) == 10^100
    sage: SR_int(SR(10^100+10^-100)) == 10^100
    sage: SR_int(SR(10^100-10^-100)) == 10^100 - 1

    sage: SR_int(sqrt(-1))
    ValueError: math domain error
    sage: SR_int(x)
    ValueError: math domain error
        if x in RR:
            ## truncate toward zero
            y = floor(abs(x))
            if parent(y) is ZZ:
                return int(ZZ(sign(x) * y))
    raise ValueError, "math domain error"

Note that floor(log(8)/log(2)) takes about 1s to complete, which means SR_int(log(8)/log(2)) is waaay slower than int(log(8)/log(2). But this is at the cost of int(x) being incorrect when x is very close to an integer (cf. int(SR(10^20-10^-20))).

OTOH, (log(8)/log(2)).full_simplify() takes 35ms to give 3, so it may be worth revisiting the floor() strategy. Opens a can of worms, I guess...

I won't turn the snippet above into a patch, if somebody likes it and wants to produce a patch, go ahead.

comment:5 Changed 10 years ago by katestange

  • Cc katestange added

comment:6 Changed 9 years ago by mjo

  • Cc mjo added

comment:7 Changed 9 years ago by burcin

  • Milestone set to sage-duplicate/invalid/wontfix
  • Reviewers set to Burcin Erocal
  • Status changed from needs_work to positive_review

#12968 has a patch with a positive review which fixes this. We should close this as a duplicate.

comment:8 Changed 9 years ago by jdemeyer

  • Summary changed from converting from symbolic ring to int is broken, to converting from symbolic ring to int is broken

comment:9 Changed 9 years ago by jdemeyer

  • Resolution set to duplicate
  • Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.