deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

Math.sumPrecise(), sıralamadan bağımsız kayan nokta toplama ile Baseline'a ulaştı

Math.sumPrecise() artık büyük tarayıcılarda Baseline oldu; iterable'ları ara yuvarlamalar olmadan topluyor ve böylece toplam, girdi sırası değiştiğinde değişmiyor. Node.js desteği hâlâ eksik.

Math.sumPrecise(), sıralamadan bağımsız kayan nokta toplama ile Baseline'a ulaştı

Kesin toplama için yeni bir yerleşik yöntem

JavaScript artık sayıları, girdi sırasından bağımsız olarak her zaman aynı sonucu döndüren standart bir yolla toplayabiliyor. Math.sumPrecise() yöntemi, MDN uyumluluk verilerine ve web.dev'in Baseline özetine atıfta bulunan dev.to'daki bir yazıya göre Nisan 2026'da Baseline (yeni kullanılabilir) durumuna ulaştı. Destek Chrome ve Edge 147, Firefox 137 ile Safari 26.2'yi kapsıyor.

Düzelttiği hata

Kayan nokta toplama iki terim için değişmelidir, ancak uzun toplama zincirleri birleşmeli değildir: her ara sonuç en yakın 64-bit double'a yuvarlanır ve bu yuvarlamalar sıralamaya göre farklı yerlere düşer. dev.to yazısı bunu, reduce() tabanlı toplamı bir sırayla 48.54, fiyata göre sıralandığında ise 48.53999999999999 okunan bir alışveriş sepetiyle gösteriyor — aynı sekiz ürün, farklı toplam.

Daha kötü durumlarda değerler tamamen kaybolur. 1e20, 0.1 ve -1e20 değerlerini bu sırayla bir reduce döngüsüyle toplamak 0 verir, çünkü 1e20 artı 0.1 doğrudan 1e20'ye geri yuvarlanır ve küçük terim, negatif değer gelmeden yok olur. 0.1'in bin kopyasını biriktirmek 99.9999999999986'ya kayar; yani naif döngü bin toplamadan sonra on ikinci basamak civarında zaten yanlıştır.

Yöntem ne yapıyor

dev.to'nun özetlediği TC39 önerisine göre belirtim, uygulamalardan tüm girdilerin gerçek matematiksel toplamını hesaplamasını ve yalnızca bir kez, nihai sonuç üretilirken bir kayan noktaya yuvarlamasını gerektiriyor. Ara yuvarlama olmadığından sıralama sonucu etkileyemez:

[1e20, 0.1, -1e20].reduce((a, b) => a + b, 0); // 0 Math.sumPrecise([1e20, 0.1, -1e20]); // 0.1

Fonksiyon yalnızca dizileri değil herhangi bir iterable'ı kabul eder; dolayısıyla Map değerleri veya bir generator doğrudan besleyebilir. Ara taşma da sonucu bozmaz: 1e308'i iki kez toplayıp bir kez çıkarmak 1e308 döndürür, oysa bir döngü yarı yolda Infinity'ye ulaşır ve asla geri dönemez. Performans, dev.to'nun bildirdiği gayri resmi Chromium 152 testinde bir sorun değil; orada bir milyon rastgele sayı Math.sumPrecise() ile yaklaşık 4 ms'de, reduce ile ise yaklaşık 16 ms'de toplandı — ancak bu tek bir makinede ölçüldü, dolayısıyla kritik yollar için kendi ölçümlerinizi yapmalısınız.

Nerede çalışıyor, nerede çalışmıyor

Öne çıkan eksik Node.js. MDN'nin uyumluluk verileri hiçbir Node sürümünü listelemiyor ve dev.to, Node 24.11 üzerinde typeof Math.sumPrecise'in "undefined" döndürdüğünü bildiriyor. Sunucu kodu veya eski tarayıcılar için dev.to, bir reduce() yedeğiyle özellik algılamayı ya da MDN'nin bağlantı verdiği core-js ve es-shims polyfill'lerini öneriyor — yedeğin eski, sıraya duyarlı davranışı geri getirdiğini de not ederek.

Bilinmeye değer keskin köşeler

  • 0.1 + 0.2 sorununu çözemez: Math.sumPrecise([0.1, 0.2]) hâlâ 0.30000000000000004 döndürür, çünkü 0.1 literal'i baştan tam olarak onda bir değildi. Yöntem, saklamadan değil toplamadan kaynaklanan hatayı ortadan kaldırır.
  • Tür dönüşümü yok. String, null ve BigInt hepsi TypeError fırlatır; dolayısıyla form girdilerinden, CSV dosyalarından veya dataset özniteliklerinden gelen değerlerin önce Number() ile dönüştürülmesi gerekir.
  • Tek bir iterable alır, spread argümanları değil — Math.sumPrecise(1, 2, 3) hata fırlatır. dev.to'ya göre bu bilinçli bir tercih, çünkü devasa bir listeyi argümanlara spread etmek stack'i taşırabilir.
  • Boş toplam -0'dır. 0 olarak yazdırılır ve eşit karşılaştırılır; yalnızca Object.is() farkı söyleyebilir.
  • Infinity ve NaN olağan şekilde yayılır: Infinity artı 1 Infinity kalır, Infinity artı -Infinity veya girdideki herhangi bir NaN ise NaN verir.
  • Para birimi hâlâ tam sayı kuruş veya BigInt ile izlenmeli. sumPrecise kayan nokta toplamlarını doğru ve kararlı kılar; kayan noktaları para için doğru araç yapmaz.

Neden önemli

Sıraya bağlı toplamlar merak değil, gerçek bir doğruluk hatasıdır: bir tabloyu sıralamak, bir veri kümesini karıştırmak veya yeni bir engine sürümü dağıtmak, kullanıcılara gösterilen ya da testlerde doğrulanan bir sayıyı sessizce değiştirebilir. Dil ilk kez, güncel her tarayıcıda kararlı ve doğru yuvarlanmış bir toplamı garanti ediyor; bu da doğruluğun önemli olduğu her kod tabanındaki her reduce((a, b) => a + b, 0) ifadesinin gözden geçirilmeyi hak ettiği anlamına gelir. Eksik Node desteği ve gösterim sınırları, onu bir panacea değil daha iyi bir varsayılan yapıyor — ama analitik, puanlama ve toplulaştırma kodu için tüm bir heisenbug sınıfını ortadan kaldırıyor.

  • #javascript
  • #floating-point
  • #baseline
  • #tc39
  • #browsers

İlgili yazılar