Türkçe

JavaScript'in BigInt türüne yönelik, özelliklerini, kullanımını ve büyük tamsayı aritmetiği uygulamalarını kapsayan kapsamlı bir rehber. JavaScript'in sınırlamalarının üstesinden gelmeyi ve karmaşık hesaplamaları hassasiyetle yapmayı öğrenin.

JavaScript BigInt: Büyük Tamsayı Aritmetiğinde Uzmanlaşma

JavaScript, çok yönlü bir dil olmasına rağmen, çok büyük tamsayılarla çalışırken sınırlamalara sahiptir. Standart `Number` türü, yalnızca `Number.MAX_SAFE_INTEGER` olarak bilinen belirli bir sınıra kadar tamsayıları doğru bir şekilde temsil edebilir. Bu sınırın ötesinde, hesaplamalar kesinliğini yitirir ve beklenmedik sonuçlara yol açar. İşte bu noktada BigInt devreye girer. ECMAScript 2020'de tanıtılan BigInt, standart `Number` türünün sınırlamalarını aşarak, keyfi boyuttaki tamsayıları temsil etme ve işleme imkanı sağlayan yerleşik bir nesnedir.

BigInt İhtiyacını Anlamak

BigInt'ten önce, JavaScript geliştiricileri büyük tamsayı hesaplamaları yapmak için kütüphanelere veya özel uygulamalara güvenmek zorundaydı. Bu çözümler genellikle performans yükü ve artan karmaşıklıkla birlikte geliyordu. BigInt'in tanıtılması, büyük tamsayılarla çalışmak için yerel ve verimli bir yol sağlayarak, aşağıdakiler de dahil olmak üzere çeşitli alanlardaki uygulamalar için olasılıkları artırdı:

BigInt Değerleri Oluşturma

JavaScript'te BigInt değerleri oluşturmanın iki ana yolu vardır:

  1. `BigInt()` yapıcısını kullanmak: Bu yapılandırıcı bir sayı, dize veya boolean değerini BigInt'e dönüştürebilir.
  2. `n` son ekini kullanmak: Bir tamsayı değişmezine `n` eklemek bir BigInt oluşturur.

Örnekler:

`BigInt()` yapıcısını kullanmak:


const bigIntFromNumber = BigInt(12345678901234567890);
const bigIntFromString = BigInt("98765432109876543210");
const bigIntFromBoolean = BigInt(true); // Sonuç 1n olur
const bigIntFromFalseBoolean = BigInt(false); // Sonuç 0n olur

console.log(bigIntFromNumber); // Çıktı: 12345678901234567890n
console.log(bigIntFromString); // Çıktı: 98765432109876543210n
console.log(bigIntFromBoolean); // Çıktı: 1n
console.log(bigIntFromFalseBoolean); // Çıktı: 0n

`n` son ekini kullanmak:


const bigIntLiteral = 12345678901234567890n;
console.log(bigIntLiteral); // Çıktı: 12345678901234567890n

Önemli Not: Aritmetik işlemlerde BigInt ve Number değerlerini doğrudan karıştıramazsınız. Hesaplamaları yapmadan önce bunları açıkça aynı türe dönüştürmeniz gerekir. Bunları doğrudan karıştırmaya çalışmak bir `TypeError` ile sonuçlanacaktır.

BigInt Aritmetik İşlemleri

BigInt, aşağıdakiler de dahil olmak üzere çoğu standart aritmetik operatörü destekler:

Örnekler:


const a = 12345678901234567890n;
const b = 98765432109876543210n;

const sum = a + b;
const difference = a - b;
const product = a * b;
const quotient = a / 2n; // Not: Bölme işlemi sıfıra doğru keser
const remainder = a % 7n;
const power = a ** 3n; // Üs alma beklendiği gibi çalışır

console.log("Toplam:", sum); // Çıktı: Toplam: 111111111011111111100n
console.log("Fark:", difference); // Çıktı: Fark: -86419753208641975320n
console.log("Çarpım:", product); // Çıktı: Çarpım: 1219326311370217957951669538098765432100n
console.log("Bölüm:", quotient); // Çıktı: Bölüm: 6172839450617283945n
console.log("Kalan:", remainder); // Çıktı: Kalan: 5n
console.log("Üs:", power); // Çıktı: Üs: 187641281029182300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n

Önemli Hususlar:

Karşılaştırma Operatörleri

BigInt değerlerini diğer BigInt değerleriyle veya hatta Number değerleriyle karşılaştırmak için standart karşılaştırma operatörlerini (`==`, `!=`, `<`, `>`, `<=`, `>=`) kullanabilirsiniz. Ancak, olası tür zorlamasına dikkat edin.

Örnekler:


const a = 10n;
const b = 20n;
const c = 10;

console.log(a == b);   // Çıktı: false
console.log(a != b);   // Çıktı: true
console.log(a < b);    // Çıktı: true
console.log(a > b);    // Çıktı: false
console.log(a <= b);   // Çıktı: true
console.log(a >= b);   // Çıktı: false

console.log(a == c);   // Çıktı: true (tür zorlaması)
console.log(a === c);  // Çıktı: false (tür zorlaması yok)

En İyi Uygulama: BigInt ve Number değerlerini karşılaştırırken beklenmedik tür zorlamasından kaçınmak için katı eşitlik (`===`) ve katı eşitsizlik (`!==`) kullanın.

BigInt ve Number Arasında Dönüşüm

BigInt ve Number arasında doğrudan aritmetik işlemlere izin verilmese de, iki tür arasında dönüşüm yapabilirsiniz. Ancak, bir BigInt değerini bir Number'a dönüştürürken, BigInt değeri `Number.MAX_SAFE_INTEGER`'ı aşarsa hassasiyet kaybı potansiyelinin farkında olun.

Örnekler:


const bigIntValue = 9007199254740991n; // Number.MAX_SAFE_INTEGER
const numberValue = Number(bigIntValue); // BigInt'i Number'a dönüştürme
console.log(numberValue); // Çıktı: 9007199254740991

const largerBigIntValue = 9007199254740992n; // Number.MAX_SAFE_INTEGER'ı aşıyor
const largerNumberValue = Number(largerBigIntValue);
console.log(largerNumberValue); // Çıktı: 9007199254740992 (kesin olmayabilir)

const numberToBigInt = BigInt(12345); // Number'ı BigInt'e dönüştürme
console.log(numberToBigInt); // Çıktı: 12345n

Kullanım Alanları ve Örnekler

Kriptografi

Kriptografik algoritmalar genellikle güvenlik için çok büyük asal sayılara dayanır. BigInt, bu sayıları verimli bir şekilde temsil etme ve işleme imkanı sağlar.


// Örnek: Basit (güvenli olmayan) bir anahtar çifti oluşturma
function generateKeyPair() {
  const p = 281n; // Bir asal sayı
  const q = 283n; // Başka bir asal sayı
  const n = p * q; // Modül
  const totient = (p - 1n) * (q - 1n); // Euler'in totient fonksiyonu

  // 1 < e < totient ve obeb(e, totient) = 1 olacak şekilde bir e (genel üs) seçin
  const e = 17n;

  // (d * e) % totient = 1 olacak şekilde bir d (özel üs) hesaplayın
  let d = 0n;
  for (let i = 1n; i < totient; i++) {
    if ((i * e) % totient === 1n) {
      d = i;
      break;
    }
  }

  return {
    publicKey: { n, e },
    privateKey: { n, d },
  };
}

const keyPair = generateKeyPair();
console.log("Genel Anahtar:", keyPair.publicKey);
console.log("Özel Anahtar:", keyPair.privateKey);

Not: Bu, yalnızca gösterim amaçlı basitleştirilmiş bir örnektir. Gerçek dünya kriptografisi çok daha büyük asal sayılar ve daha karmaşık algoritmalar kullanır.

Finansal Hesaplamalar

Büyük meblağlarla uğraşırken, özellikle uluslararası işlemlerde hassasiyet çok önemlidir. BigInt, yuvarlama hatalarını önleyebilir ve doğru hesaplamalar sağlayabilir.


// Örnek: Bileşik faiz hesaplama
function calculateCompoundInterest(principal, rate, time) {
  const principalBigInt = BigInt(principal * 100); // Cent'e dönüştür
  const rateBigInt = BigInt(rate * 10000);       // Yüzde on binde birine dönüştür
  const timeBigInt = BigInt(time);

  let amount = principalBigInt;
  for (let i = 0n; i < timeBigInt; i++) {
    amount = amount * (10000n + rateBigInt) / 10000n;
  }

  const amountInDollars = Number(amount) / 100;
  return amountInDollars;
}

const principal = 1000000; // 1.000.000 $
const rate = 0.05;    // %5 faiz oranı
const time = 10;     // 10 yıl

const finalAmount = calculateCompoundInterest(principal, rate, time);
console.log("Nihai Tutar:", finalAmount); // Çıktı: Nihai Tutar: 1628894.6267774413 (yaklaşık)

Bu örnekte, hesaplama sırasında yuvarlama hatalarından kaçınmak için anapara ve oranı BigInt değerlerine dönüştürüyoruz. Sonuç daha sonra görüntüleme için tekrar bir Number'a dönüştürülür.

Büyük ID'lerle Çalışma

Dağıtılmış sistemlerde, birden çok sunucuda benzersiz ID'ler oluşturmak zor olabilir. BigInt kullanmak, çarpışma olasılığı düşük olan çok büyük ID'ler oluşturmanıza olanak tanır.


// Örnek: Zaman damgasına ve sunucu ID'sine dayalı benzersiz bir ID oluşturma
function generateUniqueId(serverId) {
  const timestamp = BigInt(Date.now());
  const serverIdBigInt = BigInt(serverId);
  const random = BigInt(Math.floor(Math.random() * 1000)); // Biraz rastgelelik ekle

  // Benzersiz bir ID oluşturmak için değerleri birleştir
  const uniqueId = (timestamp << 20n) + (serverIdBigInt << 10n) + random;
  return uniqueId.toString(); // Kolay kullanım için bir dize olarak döndür
}

const serverId = 123; // Örnek sunucu ID'si
const id1 = generateUniqueId(serverId);
const id2 = generateUniqueId(serverId);

console.log("Benzersiz ID 1:", id1);
console.log("Benzersiz ID 2:", id2);

BigInt ve JSON

BigInt değerleri JSON tarafından yerel olarak desteklenmez. BigInt içeren bir JavaScript nesnesini `JSON.stringify()` kullanarak serileştirmeye çalışmak bir `TypeError` ile sonuçlanacaktır. JSON ile çalışırken BigInt değerlerini işlemek için birkaç seçeneğiniz vardır:

  1. Dizeye Dönüştür: Serileştirmeden önce BigInt'i bir dizeye dönüştürün. Bu en yaygın ve basit yaklaşımdır.
  2. Özel Serileştirme/Seri Durumdan Çıkarma: BigInt değerlerini işlemek için özel bir serileştirme/seri durumdan çıkarma işlevi kullanın.

Örnekler:

Dizeye Dönüştürme:


const data = {
  id: 12345678901234567890n,
  name: "Example Data",
};

// Serileştirmeden önce BigInt'i dizeye dönüştür
data.id = data.id.toString();

const jsonData = JSON.stringify(data);
console.log(jsonData); // Çıktı: {"id":"12345678901234567890","name":"Example Data"}

// Seri durumdan çıkarırken, dizeyi tekrar bir BigInt'e dönüştürmeniz gerekecektir
const parsedData = JSON.parse(jsonData, (key, value) => {
  if (key === "id") {
    return BigInt(value);
  }
  return value;
});

console.log(parsedData.id); // Çıktı: 12345678901234567890n

Özel Serileştirme/Seri Durumdan Çıkarma (`replacer` ve `reviver` kullanarak):


const data = {
  id: 12345678901234567890n,
  name: "Example Data",
};

// Özel serileştirme
const jsonData = JSON.stringify(data, (key, value) => {
  if (typeof value === 'bigint') {
    return value.toString();
  } else {
    return value;
  }
});

console.log(jsonData);

// Özel seri durumdan çıkarma
const parsedData = JSON.parse(jsonData, (key, value) => {
    if (typeof value === 'string' && /^[0-9]+$/.test(value)) { //bir sayı ve dize olup olmadığını kontrol et
      try {
        return BigInt(value);
      } catch(e) {
          return value;
      }
    }
    return value;
});

console.log(parsedData.id);

Tarayıcı Uyumluluğu

BigInt, modern tarayıcılarda yaygın olarak desteklenmektedir. Ancak, eski tarayıcılar veya ortamlar için uyumluluğu kontrol etmek önemlidir. Tarayıcı desteğini doğrulamak için Can I use gibi bir araç kullanabilirsiniz. Eski tarayıcıları desteklemeniz gerekiyorsa, bir polyfill kullanmayı düşünebilirsiniz, ancak polyfill'lerin performansı etkileyebileceğinin farkında olun.

Performans Değerlendirmeleri

BigInt büyük tamsayılarla çalışmak için güçlü bir yol sağlarken, potansiyel performans etkilerinin farkında olmak önemlidir.

Bu nedenle, BigInt'i yalnızca gerektiğinde kullanın ve çok sayıda BigInt işlemi gerçekleştiriyorsanız kodunuzu performans için optimize edin.

Sonuç

BigInt, geliştiricilerin büyük tamsayı aritmetiğini hassasiyetle ele almasını sağlayan, JavaScript'e değerli bir ektir. Özelliklerini, sınırlamalarını ve kullanım alanlarını anlayarak, kriptografi, finansal hesaplamalar ve bilimsel hesaplama dahil olmak üzere çeşitli alanlarda sağlam ve doğru uygulamalar oluşturmak için BigInt'ten yararlanabilirsiniz. Projelerinizde BigInt kullanırken tarayıcı uyumluluğunu ve performans etkilerini göz önünde bulundurmayı unutmayın.

Daha Fazla Keşif

Bu kılavuz, JavaScript'teki BigInt hakkında kapsamlı bir genel bakış sunmaktadır. Daha derinlemesine bilgi ve ileri teknikler için bağlantılı kaynakları keşfedin.