Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Another way to understand your problem is to consider what is to divide an integer by another. In general, the result of dividing an integer $n$ by an integer $d$ is

  • a quotient $q$, and
  • a remainder $r$

such as :

  • $n=q\cdot d+r$ and
  • $0\leq r\le d$

Such an operation is implemented as the quo_rem method of Sage's integers. In your examples :

sage: a = 1178491952578374405023980117478966721
sage: a.quo_rem(2)
(589245976289187202511990058739483360, 1)
sage: b=1061618174439266951056499776554456999
sage: b.quo_rem(2)
(530809087219633475528249888277228499, 1)
sage: c=1272974170381429325805079139420165714
sage: c.quo_rem(2)
(636487085190714662902539569710082857, 0)

The quotient can also be obtained by the // (integer division) operator, and the remainder by the % (modulo) operator :

sage: a//2
589245976289187202511990058739483360
sage: a%2
1
sage: b//2
530809087219633475528249888277228499
sage: b%2
1
sage: c//2
636487085190714662902539569710082857
sage: c%2
0

Your tests can be expressed as :

sage: a-(a//2)*2
1
sage: b-(b//2)*2
1
sage: c-(c//2)*2
0

Compare with :

sage: a-(a/2)*2
0
sage: b-(b/2)*2
0
sage: c-(c/2)*2
0

where the expressions a/2, b/2 and c/2 are Rationals :

sage: (a/2).parent()
Rational Field
sage: (b/2).parent()
Rational Field
sage: (c/2).parent()
Rational Field

The latter can be converted (technically coerced) to an integer :

sage: ZZ(c/2)
636487085190714662902539569710082857
sage: ZZ(c/2).parent()
Integer Ring

whereas the first one cannot :

sage: ZZ(a/2)
## Stack trace : elided
TypeError: no conversion of this rational to integer

but can be rounded to an integer :

sage: round(a/2)
589245976289187202511990058739483361
sage: round(a/2).parent()
Integer Ring

It should also be noted that Integers and Rationals are exact, in the sense that their representation is finite ; this contrasts with reals or copmplexes, whose representation may be infinite, and thus represented in machine by approximations such as the so called "floating point" numbers (floats in Python, various representations in Sage)

sage: (3/2).parent()
Rational Field
sage: (3/2).parent().is_exact()
True
sage: (1.5).parent()
Real Field with 53 bits of precision
sage: (1.5).parent().is_exact()
False

Some operations have meaning only if they are done on exact quantities (integers, rationals or algebraic). For exemple, testing the equality of two quantities by bool(x==y) means that "$x$ and $y$ are identical" if and only if x and y are exact ; if x or y are, for example, Sage's Reals with n bits of precision, the same tests succeeds if $|x'-y'|<2^{-n}$, where $x'$ and $y'$ are $x$'s and $y$'s mantissæ, i. e. numbers such as :

  • $x'2^{e_1}=x$, with $e_1\in\mathbb{Z}$, and

  • $\frac{1}{2}\leq x' \leq 1$.

This was the case of your tests : since you worked with "large" numbers, whose mantissa needed more than 53 bits for an "exact" representation, their floating point representations lost the last digits :

sage: a
1178491952578374405023980117478966721
sage: round(RR(a))
1178491952578374406338210533820334080

(In fact, you would need $\lceil \log_2a\rceil=120$ bits of precision to be able to represent a exactly, the same for b and c).

Other representations, such as intervals or balls, emphasize other aspects of the same problem.

HTH,