This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: pow(a, b, p) where b=int((p-1)/2) spits out gibbrish for big p
Type: behavior Stage: resolved
Components: Versions: Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: ammar2, b_ICT, steven.daprano
Priority: normal Keywords:

Created on 2020-04-30 05:13 by b_ICT, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (4)
msg367735 - (view) Author: b_ICT (b_ICT) Date: 2020-04-30 05:13
Hi, I was calculating Legendre coefficients, and quadratic residues and encountered what I believe to be a bug while using this code: 

for a in range (5):
        exp=int((p-1)/2)
        x=pow(a,exp,p)
        print(x)

If p is an odd prime, then x can have three values [-1,0,-1] - where "-1" refers to p-1. The code works well for reasonably small primes (like 9973). But with big primes(see below), python 3.7 spits out gibberish. Same code in python 2.7 works well.

The problem in python 3.7 can be avoided if exp is defined thusly :  
exp=(p-1)//2

Here is the prime I tried it on : 
p = 101524035174539890485408575671085261788758965189060164484385690801466167356667036677932998889725476582421738788500738738503134356158197247473850273565349249573867251280253564698939768700489401960767007716413932851838937641880157263936985954881657889497583485535527613578457628399173971810541670838543309159139
msg367736 - (view) Author: b_ICT (b_ICT) Date: 2020-04-30 05:16
Hi, I was calculating Legendre coefficients, and quadratic residues and encountered what I believe to be a bug while using this code: 

for a in range (5):
        exp=int((p-1)/2)
        x=pow(a,exp,p)
        print(x)

If p is an odd prime, then x can have three values [-1,0,1] - where (-1) refers to (p-1). The code works well for reasonably small primes (like 9973). But with big primes(see below), python 3.7 spits out gibberish. Same code in python 2.7 works well.

The problem in python 3.7 can be avoided if exp is defined thusly :  
exp=(p-1)//2

Here is the prime I tried it on : 
p = 101524035174539890485408575671085261788758965189060164484385690801466167356667036677932998889725476582421738788500738738503134356158197247473850273565349249573867251280253564698939768700489401960767007716413932851838937641880157263936985954881657889497583485535527613578457628399173971810541670838543309159139
msg367737 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-04-30 05:34
Hi,

The behaviour you are calling "gibbrish" is correct, as the expression 
`(p-1)/2` calculates a 64-bit floating point number, which may lose 
precision even for small values of p, but will definitely lose precision 
for large p.

Calling `int()` on that float will not recover the lost precision.

So there is no bug here, this is expected behaviour with floats. Please 
remember that floats are not mathematically exact Real numbers like we 
learn about in school, they have limited precision.

To avoid the float conversion, use the floor-division operator 
`(p-1)//2` as you mention. If `p` is an int, the result will be exact.
msg367738 - (view) Author: Ammar Askar (ammar2) * (Python committer) Date: 2020-04-30 05:41
And just to add on, the reason this gives you the correct result in Python 2 is that `/` performs integer division whereas in Python 3 the `/` operator provides a float as a result.

See https://docs.python.org/3/howto/pyporting.html#division for more details.
History
Date User Action Args
2022-04-11 14:59:30adminsetgithub: 84626
2020-04-30 05:42:24tim.peterssetresolution: fixed -> not a bug
2020-04-30 05:41:37ammar2setstatus: open -> closed

nosy: + ammar2
messages: + msg367738

resolution: fixed
stage: resolved
2020-04-30 05:34:53steven.dapranosetnosy: + steven.daprano

messages: + msg367737
title: pow(a,b,p) where b=int((p-1)/2) spits out gibbrish for big p -> pow(a, b, p) where b=int((p-1)/2) spits out gibbrish for big p
2020-04-30 05:16:25b_ICTsettype: behavior
messages: + msg367736
versions: + Python 3.7
2020-04-30 05:13:20b_ICTcreate