Outils pour utilisateurs

Outils du site


exponentiation

Exponentiation binaire et modulaire

Objectif

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:

http://fr.wikipedia.org/wiki/Exponentiation_modulaire

Exponentiation binaire

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

Exponentiation modulaire

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

exponentiation.txt · Dernière modification: 2012/05/03 06:58 par tyrtamos

Outils de la page