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ı:
- Kriptografi: Büyük asal sayıların güvenli bir şekilde işlenmesi, kriptografik algoritmalar için çok önemlidir.
- Finansal Hesaplamalar: Büyük parasal değerleri hassasiyet kaybı olmadan doğru bir şekilde temsil etmek.
- Bilimsel Hesaplama: Son derece büyük veya küçük sayıları içeren karmaşık hesaplamalar yapmak.
- Yüksek Hassasiyetli Zaman Damgaları: Zaman damgalarını nanosaniye hassasiyetinde temsil etmek.
- ID Oluşturma: Benzersiz ve çok büyük kimlikler oluşturmak.
BigInt Değerleri Oluşturma
JavaScript'te BigInt
değerleri oluşturmanın iki ana yolu vardır:
- `BigInt()` yapıcısını kullanmak: Bu yapılandırıcı bir sayı, dize veya boolean değerini
BigInt
'e dönüştürebilir. - `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:
- Toplama (`+`)
- Çıkarma (`-`)
- Çarpma (`*`)
- Bölme (`/`)
- Kalan (`%`)
- Üs Alma (`**`)
Ö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:
- Bölme:
BigInt
değerleriyle bölme işlemi sıfıra doğru keser. Bu, sonucun ondalık kısmının atıldığı anlamına gelir. Daha hassas bölme işlemine ihtiyacınız varsa, keyfi hassasiyetli aritmetiği destekleyen kütüphaneleri kullanmayı düşünebilirsiniz. - Tekli Artı Operatörü (+): Tekli artı operatörü (+), eski asm.js koduyla çakışacağı için
BigInt
değerleriyle kullanılamaz. Bir BigInt'i bir Sayıya dönüştürmek için (hassasiyet kaybedebileceğinizi anlayarak) sayısal bir temsile ihtiyacınız varsa `Number()` dönüştürme işlevini kullanın. - Bitsel Operatörler:
BigInt
ayrıca `&`, `|`, `^`, `~`, `<<` ve `>>` gibi bitsel operatörleri de destekler. Bu operatörler,BigInt
değerlerinin ikili gösterimi üzerinde beklendiği gibi çalışır.
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:
- 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. - Ö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.
BigInt
işlemleri, standartNumber
işlemlerinden daha yavaş olabilir.BigInt
veNumber
arasında dönüşüm yapmak da ek yük getirebilir.
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
- Mozilla Geliştirici Ağı (MDN) - BigInt
- V8 Blog - BigInt: JavaScript'te Keyfi Hassasiyetli Tamsayılar
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.