Hello, @Nasser! As @nbruin pointed out in his comment, this behavior is related to the mpfr_integer_p
function from the MPFR
library. (is_integer()
is a wrapper for that subroutine.)
Basically, Sage uses that library in order to have arbitrary precision real numbers (actually, the precision is limited by the amount of memory). In particular, if you call
type(1.0)
you will see the answer
<class 'sage.rings.real_mpfr.RealLiteral'>
Can you see the "mpfr" in there? That means that the RealLiteral
type is internally represented using the MPFR library with a little of Cython magic for the C-Python interface.
Anyway, there are good reasons to return True
when you call (1.0).is_integer()
. Mathematically speaking, $1.0$ and $1$ are the same number, so both representations are integer. (Remember that Sage is a mathematical tool/programming language.) In essence, you are asking if $1.0\in\mathbb{Z}$ is true ---which is---, i.e., you are asking about the set of integer numbers.
On the other hand, concerning your Sympy
example, notice that you are asking something different. The isinstance
function is a question from the point of view of software programming, i.e., you are asking what kind of data type is your literal 1.0
or 1
. Evidently, 1.0
is an instance of the real data type, while 1
is an instance of the integer data type.
In summary, is_integer
is a mathematical question, and isinstance
is a software programming question.
I hope this helps!
The routine is a very thin wrapper of the mpfr_integer_p mpfr library function. The approach you demonstrate for sympy would also work in sage if you adjust the types used, although the more "sagey" thing would be to look at the "parent": compare
parent(1.0)
withparent(1)
.I should note, when you write "in sympy" none of what you demonstrate actually has anything to do with SymPy and is just plain Python behavior w.r.t. the types of objects, which is an entirely language-level statement and has basically no mathematical meaning. In Python
type(1)
isint
, andtype(1.0)
isfloat
. This is asking about the language-level type that implements the value (just astype('')
isstr
). The mathematical fact (depending on the domain you're working in...) that 1.0 is the same as 1 is irrelevant here.