Ask Your Question

Revision history [back]

Each Sage object might behave differently with respect to the modulo operator %. Namely in this case this is because how this is coded in rationals numbers, namely x % y if x is rational and y integer will do the following

def modulo_for_rational(x,y):
    x = ZZ(x)
    n = x.numerator() % y
    d = x.denominator() % y
    d = d.inverse_mod(y)
    return (n * d) % y

Note that all the modulo in the above code are between integers. Hence the rationale is: in x % y with x a rational and y an integer should be considered as a computation in ZZ / y ZZ.

This is indeed inconsistent with the behavior of % when x is a floating point number... where the definition is of x % y is the unique real number in [-y/2, y/2) of the form x + n y with n integer.

sage: 3.2 % 1
0.200000000000000
sage: 3.7 % 1
-0.300000000000000

PS: you can look at the complete source code of the modulo operator with

sage: Rational.__mod__??

Each Sage object might behave differently with respect to the modulo operator %. Namely in your situation this case this is because how this is coded in rationals numbers, namely of the implementation within rational numbers. Namely x % y if x is rational and y integer will do the following

def modulo_for_rational(x,y):
    x = ZZ(x)
    n = x.numerator() % y
    d = x.denominator() % y
    d = d.inverse_mod(y)
    return (n * d) % y

Note that all the modulo in the above code are between integers. Hence the rationale is: in x % y with x a rational and y an integer should be considered as a computation in ZZ / y ZZ.

This is indeed inconsistent with the behavior of % when x is a floating point number... where the definition is of x % y is the unique real number in [-y/2, y/2) of the form x + n y with n integer.

sage: 3.2 % 1
0.200000000000000
sage: 3.7 % 1
-0.300000000000000

PS: you can look at the complete source code of the modulo operator with

sage: Rational.__mod__??

Each Sage object might behave differently with respect to the modulo operator %. Namely in In your situation this is because of due to the implementation within of this operator for rational numbers. Namely x % y if x is rational and y integer Sage will do the following

def modulo_for_rational(x,y):
    x = ZZ(x)
    n = x.numerator() % y
    d = x.denominator() % y
    d = d.inverse_mod(y)
    return (n * d) % y

Note that all the modulo in the above code are between integers. Hence the rationale is: in x % y with x a rational and y an integer should be considered as a computation in ZZ / y ZZ.

This is indeed inconsistent with the behavior of % when x is a floating point number... where the definition is of x % y is the unique real number in [-y/2, y/2) of the form x + n y with n integer.

sage: 3.2 % 1
0.200000000000000
sage: 3.7 % 1
-0.300000000000000

PS: you can look at the complete source code of the modulo operator with

sage: Rational.__mod__??