2013-09-21 5 views
5

Perché il passaggio a un numero intero espresso come un numero in virgola mobile dà risultati diversi all'innalzamento dello stesso numero nella sua forma intera?pow() sollevamento a float

Es .:

>>> pow(10,25)%195 
10L 
>>> pow(10,25.0)%195 
64.0 

Ho provato con mpmath's power() invece, ma ottenere gli stessi numeri esatti - e l'errore - come la seconda forma.

Come posso elevare a potenze non grandi di interi molto grandi ed eseguire mod su di esse (ad esempio i passaggi per eseguire una logica simile a RSA usando la matematica pura) in Python?

+2

[Ciò che ogni scienziato informatico dovrebbe sapere sull'aritmetica a virgola mobile] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – orlp

+0

Perché è necessario? RSA non usa esponenti non interi . – Aleph

+0

@AnotherTest sì, stavo guardando il modulo come è stato colpito da come RSA fosse, * tranne * che ho un esponente non intero. – Will

risposta

6

Per gli interi, è possibile utilizzare il modulo a 3 argomento di pow:

pow(10, 25, 195) 

tuo problema qui deriva dalla perdita di precisione in carri allegorici. È necessario utilizzare decimal.Decimal s qui:

>>> from decimal import Decimal 
>>> pow(10, Decimal('25.0')) % 195 
Decimal('10') 
4

Per rispondere alla tua domanda, perché galleggia in Python sono IEEE754 floats and have limited precision.

>>> int(10**25.0) 
10000000000000000905969664L 

Come si può vedere, la risposta è vicina ma errata.

Come posso alzare a molto grandi potenze non interi ed eseguire mod su di loro (ad esempio misure adottate per eseguire logica RSA-come l'utilizzo di pura matematica) in Python?

Questo è il mio suggerimento usando x^(a+b) = x^a * x^b:

def powmod_f(base, exponent, mod): 
    return (pow(base, int(exponent), mod) * (base ** (exponent % 1))) % mod 

Questo funziona solo con una base integer tuttavia, se la base è un galleggiante e si sta andando ad avere per implementare un algoritmo POWMOD te stesso.