Math.powExact în Java

Putere și înmulțire întreagă exactă (Java 25): rezultat int/long sau ArithmeticException la overflow, inclusiv pentru numere fără semn.

Sintaxă
static int powExact(int x, int n)   // și long
static int unsignedPowExact(int x, int n)   // și long
static int unsignedMultiplyExact(int x, int y)   // și long

Ce face Math.powExact

Math.powExact(x, n) calculează xn în întregi, fără să treacă prin double, și aruncă ArithmeticException dacă rezultatul nu încape în int (sau long). Exponentul n trebuie să fie ≥ 0; un exponent negativ aruncă tot ArithmeticException.

unsignedPowExact și unsignedMultiplyExact tratează valorile ca numere fără semn: un int poate atunci ține până la 4294967295, iar un long până la 18446744073709551615. Rezultatul are aceiași biți, dar trebuie afișat cu Integer.toUnsignedString sau Long.toUnsignedString, altfel apare ca număr negativ. Toate trei au apărut în Java 25.

Parametri

Parametru Descriere
x Baza (sau primul factor).
n Exponentul, ≥ 0.
y Pentru unsignedMultiplyExact: al doilea factor.

Ce returnează

Rezultatul exact, ca int sau long.

Exemple

Exemplul 1: Puteri exacte

Ultimul rând arată problema variantei cu double: conversia (int) a lui 1010 dă în tăcere Integer.MAX_VALUE.

public class Main {
    public static void main(String[] args) {
        System.out.println(Math.powExact(3, 10));
        System.out.println(Math.powExact(10L, 18));
        try {
            System.out.println(Math.powExact(10, 10));
        } catch (ArithmeticException e) {
            System.out.println("10^10 în int: " + e.getMessage());
        }
        System.out.println((int) Math.pow(10, 10));
    }
}

Rezultat

59049
1000000000000000000
10^10 în int: integer overflow
2147483647

Exemplul 2: Numere fără semn

231 nu încape într-un int cu semn, dar încape fără semn. 232 nu mai încape nici așa.

public class Main {
    public static void main(String[] args) {
        int a = Math.unsignedPowExact(2, 31);
        System.out.println(a + " / fără semn: " + Integer.toUnsignedString(a));
        int b = Math.unsignedMultiplyExact(65536, 65535);
        System.out.println(Integer.toUnsignedString(b));
        try {
            Math.unsignedPowExact(2, 32);
        } catch (ArithmeticException e) {
            System.out.println("2^32: " + e.getMessage());
        }
    }
}

Rezultat

-2147483648 / fără semn: 2147483648
4294901760
2^32: unsigned integer overflow

Greșeli frecvente

  • Afișezi rezultatul unei operații fără semn direct: System.out.println(a) arată un număr negativ. Folosește Integer.toUnsignedString(a).
  • Folosești (long) Math.pow(10, 19) pentru întregi mari: valoarea depășește long și este tăiată la Long.MAX_VALUE fără eroare. powExact semnalează problema.

Comenzi înrudite

  • Math.pow: Ridică un număr la o putere și returnează rezultatul ca double; exponentul poate fi și negativ sau cu zecimale.
  • Math.addExact: Adunare, scădere, înmulțire, incrementare și negare care aruncă ArithmeticException la overflow în loc să dea rezultat greșit.
  • Math.multiplyFull: multiplyFull înmulțește două int-uri cu rezultat long complet; multiplyHigh dă jumătatea de sus a produsului a două long-uri.
  • Integer.toBinaryString: Afișează biții unui int în binar sau în hexazecimal și numără câți biți de 1 are.