PDA

View Full Version : [C#] funzione per potenze con base negativa ed esponente non intero


grigor91
06-12-2010, 13:31
Salve.
La funzione Math.Pow() se utilizzata con una base negativa ed un esponente non intero ritorna NaN. Vorrei sapere se esiste una funzione bult-in che invece riesce risolvere correttamente questo tipo di potenze?

Mi sembra strano che (-8)^(1/3) così difficile da risolvere.

gugoXX
06-12-2010, 19:34
La funzione x^y, per qualsiasi x<0 non e' continua in R. Non esiste per tutto il dominio, e non e' nemmeno continua a tratti. E' una brutta bestia tutta sparsa.
-8^1/2 non si puo' fare.
-8^1/3 si puo' fare
-8^(72/213) si puo' fare
-8^1/Sqrt(2) men che meno si puo' fare.
-8^1/e ancora di meno.

A parte tutti i valori positivi di y, si puo' calcolare per ogni y€N-, piu' ogni y€ a/b tali che a e b siano entrambi interi e in piu' b sia dispari.

Ti conviene passare da una funzione che cucini tale fattore e restituisca eventualmente il valore cercato quando i parametri in input siano corretti.

Supdario
06-12-2010, 20:01
Salve.
La funzione Math.Pow() se utilizzata con una base negativa ed un esponente non intero ritorna NaN. Vorrei sapere se esiste una funzione bult-in che invece riesce risolvere correttamente questo tipo di potenze?

Mi sembra strano che (-8)^(1/3) così difficile da risolvere.

Questo è dovuto al fatto che prima viene svolto il calcolo 1/3, che viene successivamente approssimato (0.33333334 per un float a 32bit), di conseguenza viene eseguito il calcolo -8^0.33333334, che è impossibile da eseguire perché è impossibile determinare se l'esponente è pari o dispari.

In questo caso ti ci vorrebbe un calcolatore che sfrutta un motore algebrico (cosa che fanno solo alcuni programmi come Derive o Microsoft Math), oppure nel tuo caso, ti ci vuole una funzione che esegua la radice N_esima di un numero.
Oppure può anche andar bene un workaround, come questo:


public double potenza(double x, double y)
{
if (x < 0 && y < 1)
return (-Math.Pow(-x, y));
else
return Math.Pow(x, y);
}

grigor91
07-12-2010, 11:11
Questo è dovuto al fatto che prima viene svolto il calcolo 1/3, che viene successivamente approssimato (0.33333334 per un float a 32bit), di conseguenza viene eseguito il calcolo -8^0.33333334, che è impossibile da eseguire perché è impossibile determinare se l'esponente è pari o dispari.

In questo caso ti ci vorrebbe un calcolatore che sfrutta un motore algebrico (cosa che fanno solo alcuni programmi come Derive o Microsoft Math), oppure nel tuo caso, ti ci vuole una funzione che esegua la radice N_esima di un numero.
Oppure può anche andar bene un workaround, come questo:


public double potenza(double x, double y)
{
if (x < 0 && y < 1)
return (-Math.Pow(-x, y));
else
return Math.Pow(x, y);
}


Infatti ho risolto cambiando il segno prima alla base e dopo al risultato, volevo sapere se esisteva qualcosa di migliore già pronto.
Grazie.

gugoXX
07-12-2010, 22:13
Si, ma e' sbagliato.

-9 ^ (0.5) non e' -3.

grigor91
08-12-2010, 10:03
Si, ma e' sbagliato.

-9 ^ (0.5) non e' -3.

La mia intenzione è quella di creare una semplicissima funzione per risolvere una radice con indice maggiore di 2. Il parametro sarà quindi il radicando e l'indice, che sarà denominatore dell'esponente di Pow. Ovviamente se il radicando è negativo la funzione accetterà solo indici dispari.

La mia perplessità riguarda il fatto che vista la relativa frequenza di di questo tipo di calcoli, ci fossero già delle soluzioni built-in.

Supdario
08-12-2010, 11:51
Si, ma e' sbagliato.

-9 ^ (0.5) non e' -3.

Sì, è vero, in questo caso diventa impossibile. Al massimo si può modificare la funzione così:

public double potenza(double x, double y)
{
if (x < 0 && y < 1 && Convert.ToInt32(1/y)%2 != 0)
return (-Math.Pow(-x, y));
else
return Math.Pow(x, y);
}

Ho aggiunto la condizione che controlla se il reciproco dell'esponente è dispari. In questo modo dovrebbe funzionare per tutti i casi penso.