# Sage - problem during dividing

I'm using https://sagecell.sagemath.org/ I tried divide by 2 some integers like:

test no 1:
integer to divide                                      : 1178491952578374405023980117478966721
after divide by 2                                      :  589245976289187203169105266910167040
multiply by 2 to get integer before divide : 1178491952578374406338210533820334080

test no 2:
integer to divide                                      : 1061618174439266951056499776554456999
after divide by 2                                      : 530809087219633493358671479116398592
multiply by 2 to get integer before divide : 1061618174439266986717342958232797184

test no 3:
integer to divide                                      : 1272974170381429325805079139420165714
after divide by 2                                      : 636487085190714687068002546205327360
multiply by 2 to get integer before divide : 1272974170381429374136005092410654720


why result after divide is wrong??

If I change language from sage to python is even worst...

code:

    import random

def delete_0(value):
report = False
len_s=len(value)
while report == False:
if value[len_s-1] == "0":

report = False
#print("przed :",value)
value=value[:-1]
#print("po :",value)
len_s=len(value)
if value[len_s-1] != "0":
report = True
if len(value)==1:
report = True
return value

def printStr(FloatNumber, Precision):
return "%0.*f" % (Precision, FloatNumber)

def gen_value(liczba):
d = liczba

l =[]

ile = len(str(d))
w = printStr(d,ile)
l = str(w).split(".")
w = l
r = delete_0(w)
return l +"."+r

#number to divide as random.randrange
number =  1272974170381429325805079139420165714 #random.randrange((2**119),2**120)

to_test = number
print("number to divide by 2 : ",number)

number =(number /2)
print("i-th divide: ",i," # after divide : ",number)
print("i-th divide: ",i," # after divide : ",Reals(120)(number))
print("number as more precisied: ",gen_value(number))

print("Test : after multiply * 2 is equal? ",(float(number)+float(number) ) == to_test)

edit retag close merge delete

Please display your test code. And also operating system, sage version, etc

Sort by » oldest newest most voted

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,

more Python's float does not have high precision, and when you do the division number/2 in Python, that's what you get. Try replacing number with Integer(number) to make sure you use Sage's arbitrary precision integers; once you've done that, then any divisions (for example) involving these integers will remain exact. Try to avoid converting to float either explicitly or implicitly. Here is an example illustrating some differences between Sage Integer and Python int: Sage

sage: type(4)
<class 'sage.rings.integer.Integer'>
sage: 4/3
4/3
sage: type(4/3)
<class 'sage.rings.rational.Rational'>
sage: 3 * 4/3
4


as compared to Python

>>> type(4)
<class 'int'>
>>> 4/3
1.3333333333333333
>>> type(4/3)
<class 'float'>
>>> 3 * 4/3
4.0


Also, you lose precision when you move from Sage numeric types to Python ones:

sage: a = 117849195257837440502398011747896672
sage: a
117849195257837440502398011747896672
sage: int(float(a))
117849195257837440633821053382033408

more