Come già accennato, l'utilizzo di un tipo di dati "più grande" consente la convalida e il calcolo semplice - ma cosa succede se non c'è un tipo di dati più grande??
È possibile matematicamente prova, se si tradurrebbe in un overflow:
Se si caluclating base^power
, questo significa base^power = result
- significa anche power-th square of result = base
- il massimo risultato consentito è Integer.MAX_VALUE
- altrimenti si ha un overflow.
La power-th root
di qualsiasi numero maggiore di zero sarà SEMPRE essere all'interno della gamma ]0,number]
- nessuna possibilità di aritmetica overflow.
Quindi - confrontiamo la base
che si sta utilizzando con il power-th root
di Integer.MAX_VALUE
- è base
GRANDE? Poi si verifica un trabocco - altrimenti sarebbe attaccare soffietto (o essere uguale) al risultato di Integer.MAX_VALUE
private static double powSafe(double base, int pow){
//this is the p-th root of the maximum integer allowed
double root = Math.pow(Integer.MAX_VALUE, 1.0/pow);
if (root < base){
throw new ArithmeticException("The calculation of " + base + "^" + pow + " would overflow.");
}else{
return Math.pow(base, pow);
}
}
public static void main(String[] argv)
{
double rootOfMaxInt = Math.pow(Integer.MAX_VALUE, 1.0/2);
try{
//that should be INTEGER.MAX_VALUE, so valid.
double d1 = powSafe(rootOfMaxInt, 2);
System.out.println(rootOfMaxInt + "^2 = " + d1);
}catch (ArithmeticException e){
System.out.println(e.getMessage());
}
try{
//this should overflow cause "+1"
double d2 = powSafe(rootOfMaxInt +1, 2);
System.out.println("("rootOfMaxInt + "+ 1)^2 = " + d1);
}catch (ArithmeticException e){
System.out.println(e.getMessage());
}
double the67thRootOfMaxInt = Math.pow(Integer.MAX_VALUE, 1.0/67);
try{
//and so, it continues
double d3 = powSafe(the67thRootOfMaxInt, 67);
System.out.println(the67thRootOfMaxInt + "^67 = " + d3);
double d4 = powSafe(the67thRootOfMaxInt +1, 67);
System.out.println("(" + the67thRootOfMaxInt + " + 1)^67 = " + d3);
}catch (ArithmeticException e){
System.out.println(e.getMessage());
}
}
porta a
46340.950001051984^2 = 2.147483647E9
The calculation of 46341.950001051984^2 would overflow.
1.3781057199632372^67 = 2.1474836470000062E9
The calculation of 2.378105719963237^67 would overflow.
nota, che ci sono imprecisioni che appaiono causa doppio non ha alcun infinita precisione, che già tronca l'espressione 2nd square of Integer.Max_Value
, causa Integer.Max_value
è dispari.
è possibile convertire la base e l'alimentazione in 'BigDecimals', quindi confrontare i risultati con' Integer.MAX_VALUE' – user902383
@ user902383 mentre si ha assolutamente ragione per il caso 'int' (dove è possibile utilizzare' bigint' per convalidare) sarebbe interessante come puoi gestirlo per 'bigints' allora? – dognose
In alternativa è possibile dividere Integer.MAX_VALUE per base e quando il risultato sarà superiore a tale valore, errore di ritorno – user902383