Math.multiplyFull în Java

multiplyFull înmulțește două int-uri cu rezultat long complet; multiplyHigh dă jumătatea de sus a produsului a două long-uri.

Sintaxă
static long multiplyFull(int x, int y)
static long multiplyHigh(long x, long y)
static long unsignedMultiplyHigh(long x, long y)   // Java 18

Ce face Math.multiplyFull

Math.multiplyFull(x, y) înmulțește două int-uri și returnează produsul complet ca long. Este echivalent cu (long) x * y, dar arată clar intenția și evită greșeala (long) (x * y), unde înmulțirea dă overflow înainte de conversie.

Produsul a două numere long poate avea până la 128 de biți. Math.multiplyHigh(x, y) returnează cei 64 de biți de sus ai produsului (cei de jos sunt chiar x * y). unsignedMultiplyHigh (Java 18) face la fel, dar tratează numerele ca fără semn. Aceste metode sunt folosite în algoritmi de numere mari, criptografie și funcții hash; în programele obișnuite apar rar.

Parametri

Parametru Descriere
x, y Cei doi factori.

Ce returnează

Un long: produsul complet (multiplyFull) sau partea lui de sus (multiplyHigh).

Exemple

Exemplul 1: Produsul a două int-uri mari

public class Main {
    public static void main(String[] args) {
        int locuitori = 19_050_000;
        int taxa = 250;
        long gresit = (long) (locuitori * taxa);
        long corect = Math.multiplyFull(locuitori, taxa);
        System.out.println("Greșit: " + gresit);
        System.out.println("Corect: " + corect);
    }
}

Rezultat

Greșit: 467532704
Corect: 4762500000

Exemplul 2: Partea de sus a unui produs de 128 de biți

262 × 8 = 265. Partea de sus este 2 (adică 265 / 264), iar partea de jos este 0. Cu semn, -1 × -1 = 1, deci partea de sus este 0. Fără semn, -1 înseamnă 264 − 1, iar partea de sus a pătratului său este 264 − 2, afișată ca -2 pentru că long are semn.

public class Main {
    public static void main(String[] args) {
        long x = 1L << 62;
        long y = 8;
        System.out.println("sus: " + Math.multiplyHigh(x, y));
        System.out.println("jos: " + x * y);
        System.out.println(Math.multiplyHigh(-1L, -1L));
        System.out.println(Math.unsignedMultiplyHigh(-1L, -1L));
    }
}

Rezultat

sus: 2
jos: 0
0
-2

Greșeli frecvente

  • Scrii (long) (a * b): conversia vine prea târziu. Scrie (long) a * b sau Math.multiplyFull(a, b).
  • Cauți multiplyFull pentru două long-uri: nu există, pentru că rezultatul n-ar încăpea. Folosește multiplyHigh împreună cu x * y sau BigInteger.

Comenzi înrudite

  • Math.addExact: Adunare, scădere, înmulțire, incrementare și negare care aruncă ArithmeticException la overflow în loc să dea rezultat greșit.
  • Math.powExact: Putere și înmulțire întreagă exactă (Java 25): rezultat int/long sau ArithmeticException la overflow, inclusiv pentru numere fără semn.
  • Long.parseLong: Long este wrapperul pentru long (întregi pe 64 de biți); parseLong și valueOf transformă textul în număr.