Pour certains calculs portant sur les calculs de puissance (x**y) et de puissance modulaire (x**y%z) des nombres entiers longs, on est quelquefois obligé de les programmer, et le calcul direct est beaucoup trop long: on va donner ici une méthode plus rapide.
Ce n'est cependant pas utile dans les dernières versions de Python: la fonction pow(x,y) et pow(x,y,z) fait ça très bien, et plus rapidement. Il y a cependant un petit problème: la fonction 'pow' du Python de base n'est pas identique à la fonction 'pow' du module math: cette dernière ne supporte pas l'exponentiation modulaire (le 3e argument). Une solution est de renommer le 'pow' de base de la façon suivante:
from __builtin__ import pow as powmod x = powmod(a,b,c)
Ainsi, on peut faire de l'exponentiation modulaire même lorsqu'on a besoin d'importer le module math comme 'from math import *'.
Un site pour l'exponentiation binaire:
http://www.labri.fr/perso/betrema/deug/poly/exp-rapide.html
Un site pour l'exponentiation modulaire:
Code proposé:
def lpow(x,y): """Calcul rapide de la puissance entière avec x et y entiers """ result = 1 while y != 0: if y&1 == 1: # si y impair result *= x y -= 1 else: # y est pair x *= x y >>= 1 return result
Exemple d'application:
lpow(231, 729) 11834048405730720093227288066140033921133210283721116745483349401149687016037947980014962315154827138906229380914012943309612043795490172585302642776307674416447874444048128778605656549533167834248414850766358743574515663915238152118531248824070892028025158057673326296246629484228072585538370539534086321719866318045334832888906905334393094373691463510659107398301274168487625657368955255131330708544531915018198372222504767437487875824441718683336654896761842302125315155571601680274831378427408722471146113156998310458014310934220076671392695143424642557053045297179317090194607713207147168311797813782619124924202804657094338738400224695025367888198653879846688262993910164478809271453014878419567581836354288509320717959160546656166963787313457846408445250547034396508916262913692077940563140051267872404236195188621594763586355474991492832552351202813085624220949975270694234537474974608570057385569755533317202903102748272788493728665759220084679199925666001698034443952456144849251630899591497568017400158299189278206658663663192821484122344835554108063006185079067285852443905941928984232908699528814589431627091340462808477172607689520648403825346489626962551370673429351153742491874700405694432645019453056164818865000785616706756089450375423093986868623010740844302093720954460551829047614145147915430015006412969980640273387465748278737725195074428228299426797340094372439852701549062865557657380060498496229783608571967097803457559444096870116545269231679753836757807773207808330242092255768628311028164271220474061849543376327237865889621561105369497883618367444096715088101676212943221501906727384469689807175319542254798804804533653301953147952907850458488210688543707776520095702250571135262271668240028071
def lpowmod(x, y, n): """puissance modulaire: (x**y)%n avec x, y et n entiers""" result = 1 while y>0: if y&1>0: result = (result*x)%n y >>= 1 x = (x*x)%n return result
Exemple d'application:
lpowmod(125,687,15) 5 lpowmod(555,635,117) 81 lpowmod(873,185,67) 41