Eğitim Portalı/Java/Math Sınıfı
Java01-java/75-math-sinifi

Math Sınıfı

Math, matematiksel işlemler için statik metotlar ve sabitler sunan yardımcı sınıftır. Mutlak değer, üs/kök, yuvarlama, trigonometri, logaritma... hepsi buradadır. Ayrıca bu konu, sayılarla çalışırken her geliştiricini…

Math Sınıfı

Math, matematiksel işlemler için statik metotlar ve sabitler sunan yardımcı sınıftır. Mutlak değer, üs/kök, yuvarlama, trigonometri, logaritma... hepsi buradadır. Ayrıca bu konu, sayılarla çalışırken her geliştiricinin er geç karşılaştığı iki kritik tuzağı — kayan nokta hatası ve tam sayı taşması — ve çözümlerini ele alır.

Temel metotlar

Math.abs(-7);          // mutlak değer
Math.max(a, b); Math.min(a, b);
Math.pow(2, 10);       // üs (2^10) — double döndürür
Math.sqrt(144); Math.cbrt(27);  // kare/küp kök
Math.round(3.67);      // en yakın tam sayı -> 4
Math.floor(3.67);      // aşağı -> 3.0
Math.ceil(3.67);       // yukarı -> 4.0
Math.hypot(3, 4);      // hipotenüs -> 5.0
Math.random();         // [0.0, 1.0) rastgele double
Math.PI, Math.E;       // sabitler

Trigonometri (sin/cos/tan) radyan ile çalışır; toRadians/toDegrees ile dönüştür. Örnek 1 (./Ornek1.java) bunları gösterir.

Dikkat: pow ve çoğu metot double döndürür. Tam sayı sonuç istiyorsan (int) cast'le veya Math.round kullan. Daha kaliteli rastgelelik için java.util.Random / ThreadLocalRandom.

Tuzak 1: Kayan nokta hatası

double/float, sayıları ikili tabanda tutar ve 0.1 gibi ondalık kesirleri tam olarak gösteremez. Sonuç:

0.1 + 0.2 == 0.3   // FALSE!  (sonuç 0.30000000000000004)

Bu bir Java hatası değil, IEEE 754 kayan nokta aritmetiğinin doğasıdır. Çözümler:

  • Para/finans/hassas hesap: BigDecimal kullan — ve mutlaka String constructor ile (new BigDecimal("0.1"); new BigDecimal(0.1) yine hatalı double'dan başlar).
  • Karşılaştırma: İki double== ile karşılaştırma; küçük bir tolerans (epsilon) kullan: Math.abs(a - b) < 1e-9.
new BigDecimal("0.1").add(new BigDecimal("0.2"));  // tam 0.3
fiyat.setScale(2, RoundingMode.HALF_UP);           // 2 ondalık, yuvarlama kuralı

Tuzak 2: Tam sayı taşması

int/long sınırlıdır. Integer.MAX_VALUE'yu aşan işlem sessizce sarmalanır (negatife döner) — hiçbir uyarı vermez:

Integer.MAX_VALUE + 1   // -2147483648  (taştı!)

Çözümler:

  • Math.addExact/multiplyExact/subtractExact: Taşmada ArithmeticException atar (sessiz bozuk sonuç yerine açık hata).
  • Daha geniş tip: long (veya çok büyük sayılar için BigInteger).

Örnek 2 (./Ornek2.java) her iki tuzağı ve çözümlerini canlı gösterir.

StrictMath ve performans

Math, platforma göre donanım hızlandırması kullanabilir (sonuçlar platformlar arası çok küçük farklılık gösterebilir). Bit-bit aynı sonuç gereken nadir durumlarda StrictMath kullanılır (daha yavaş ama tam tekrarlanabilir).

Özet

Math sınıfının matematiksel metotlarını ve sabitlerini (Örnek 1); sayılarla çalışırken iki kritik tuzağı — kayan nokta hatası (çözüm: BigDecimal + epsilon) ve tam sayı taşması (çözüm: Math.addExact/long) — (Örnek 2) öğrendik. Bu tuzakları bilmek, özellikle finansal hesaplarda hata yapmanı önler. Sırada, sayı tipleri ve otomatik kutulama: wrapper sınıfları ve autoboxing.

Kod Örnekleri(2)

Ornek1

çalıştırılabilir
Ornek1.java
1// Ornek1: Math sınıfı — temel matematiksel işlemler.
2// Çalıştırma: java Ornek1.java
3public class Ornek1 {
4
5    public static void main(String[] args) {
6        // Mutlak değer, min/max
7        System.out.println("abs(-7)    = " + Math.abs(-7));
8        System.out.println("max(3, 9)  = " + Math.max(3, 9));
9        System.out.println("min(3, 9)  = " + Math.min(3, 9));
10
11        // Üs ve kök
12        System.out.println("pow(2, 10) = " + Math.pow(2, 10));   // 2^10 = 1024 (double)
13        System.out.println("sqrt(144)  = " + Math.sqrt(144));
14        System.out.println("cbrt(27)   = " + Math.cbrt(27));     // küp kök
15
16        // Yuvarlama
17        double d = 3.67;
18        System.out.println("\nround(3.67) = " + Math.round(d)); // en yakın -> 4
19        System.out.println("floor(3.67) = " + Math.floor(d));   // aşağı -> 3.0
20        System.out.println("ceil(3.67)  = " + Math.ceil(d));    // yukarı -> 4.0
21        System.out.println("round(3.49) = " + Math.round(3.49));// -> 3
22
23        // Sabitler ve geometri
24        System.out.printf("%nPI = %.5f, E = %.5f%n", Math.PI, Math.E);
25        System.out.println("hypot(3, 4) = " + Math.hypot(3, 4)); // dik üçgen hipotenüsü -> 5.0
26        double aci = Math.toRadians(30);
27        System.out.printf("sin(30°) = %.2f%n", Math.sin(aci));
28
29        // Rastgele sayı [0.0, 1.0)
30        double r = Math.random();
31        System.out.println("\nrandom() 0-1 arası mı? " + (r >= 0 && r < 1));
32        int zar = (int) (Math.random() * 6) + 1; // 1-6
33        System.out.println("zar (1-6): " + zar);
34
35        System.out.println("""
36
37                --- Math sınıfı ---
38                Tüm metotları statiktir: Math.abs/max/min/pow/sqrt/cbrt, round/floor/ceil, sin/cos/tan,
39                log/exp, hypot, toRadians/toDegrees; sabitler Math.PI ve Math.E.
40                round: en yakın tam sayı; floor: aşağı; ceil: yukarı. random(): [0,1) double.
41                NOT: pow ve çoğu metot DOUBLE döndürür; tam sayı sonucu için (int) cast veya Math.round.
42                Daha iyi rastgelelik için java.util.Random / ThreadLocalRandom; finansal hassasiyet için BigDecimal.""");
43    }
44}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek2

çalıştırılabilir
Ornek2.java
1// Ornek2: Sayısal tuzaklar — kayan nokta hatası, tam sayı taşması ve çözümleri.
2// Çalıştırma: java Ornek2.java
3import java.math.BigDecimal;
4import java.math.RoundingMode;
5
6public class Ornek2 {
7
8    public static void main(String[] args) {
9        // 1) KAYAN NOKTA HATASI: 0.1 + 0.2 != 0.3 (double ikili tabanda kesirleri tam tutamaz)
10        double toplam = 0.1 + 0.2;
11        System.out.println("0.1 + 0.2 = " + toplam + "  (0.3 BEKLENİRDİ!)");
12        System.out.println("== 0.3 ? " + (toplam == 0.3));
13
14        // Çözüm: para/hassas hesap için BigDecimal (String constructor ile!)
15        BigDecimal a = new BigDecimal("0.1");
16        BigDecimal b = new BigDecimal("0.2");
17        System.out.println("BigDecimal: " + a.add(b) + "  (tam 0.3)");
18        BigDecimal fiyat = new BigDecimal("19.99").multiply(new BigDecimal("3"))
19                .setScale(2, RoundingMode.HALF_UP);
20        System.out.println("19.99 * 3 = " + fiyat);
21
22        // 2) TAM SAYI TAŞMASI: int max'ı aşınca sessizce sarmalanır (negatife döner!)
23        int max = Integer.MAX_VALUE;
24        System.out.println("\nInteger.MAX_VALUE = " + max);
25        System.out.println("max + 1 = " + (max + 1) + "  (TAŞTI -> negatif!)");
26
27        // Çözüm: Math.addExact taşmada exception atar (sessiz hata yerine)
28        try {
29            Math.addExact(max, 1);
30        } catch (ArithmeticException e) {
31            System.out.println("Math.addExact -> " + e.getMessage() + " (taşma yakalandı)");
32        }
33        // veya long kullan:
34        System.out.println("long ile: " + ((long) max + 1));
35
36        System.out.println("""
37
38                --- Sayısal tuzaklar ---
39                Kayan nokta: double/float ikili tabanda 0.1 gibi kesirleri TAM tutamaz -> yuvarlama hatası.
40                  Para/finans hesabında BigDecimal kullan (üstelik new BigDecimal(\"0.1\") gibi STRING ile).
41                Tam sayı taşması: int/long sınırı aşılınca SESSİZCE sarmalanır (negatife döner).
42                  Math.addExact/multiplyExact taşmada exception atar; ya da daha geniş tip (long) kullan.
43                Kural: eşitlik için double'ı '==' ile karşılaştırma; küçük bir tolerans (epsilon) kullan.""");
44    }
45}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.