· kaynak dev.to (home feed)
rust_decimal'ın varsayılan parse'ı token tutarlarının son wei'sini düşürürken Ok döndürüyor
Dev.to'da yayınlanan bir Rust para tipi karşılaştırması, rust_decimal'ın from_str fonksiyonunun 30 haneli bir token tutarını kabul ederken son hanesini sessizce attığını gösteriyor; aynı girdi üzerinde from_str_exact ise Err(Underflow) döndürüyor.

Gönderdiğinizden daha az haneyle başarılı olan bir parse
Fintech ve kripto ödemeleri geliştiricisi Tom Wang'ın dev.to'da yayınladığı Rust para tipleri karşılaştırmasına göre, rust_decimal'ın varsayılan string kurucusu, tam olarak saklayamadığı girdi için başarı bildiriyor.
Demonstrasyon: "100000000000.000000000000000001" girdisi üzerinde Decimal::from_str çağırmak Ok döndürüyor, ancak saklanan değer 100000000000.00000000000000000 oluyor. Girdi on iki tam sayı hanesi ve on sekiz kesirli hane taşıyor — otuz anlamlı hane — buna karşılık rust_decimal'ın 96-bit mantiss'ı yirmi sekiz hane tutuyor. Sondaki 1, 18 ondalıklı bir token tutarında son wei olan değer, hataya neden olmadan değerin sığması için atılıyor. Aynı string'i Decimal::from_str_exact ile işlemek ise Err(Underflow) üretiyor.
Wang, davranışı rust_decimal 1.43.0, bigdecimal 0.4.11 ve Rust 1.98 ile bir deneme crate'inde doğruladığını, her çıktının o çalışmadan kopyalandığını söylüyor. Dev.to yazısı, yazarın kendi sitesindeki daha uzun bir incelemeyi özetliyor; yani karşılaştırma upstream bir hata raporu değil, tek bir geliştiricinin ölçümü.
Tipin bu şekilde davranmasının nedeni
rust_decimal bir ondalık sayıyı 16 sabit bayta sığdırıyor: 96-bit bir tam sayı, 0 ile 28 arasında bir scale ve bir işaret biti. Bu, ±79,228,162,514,264,337,593,543,950,335'e kadar kesin değerler, Copy semantiği ve heap tahsisisi olmaması sağlıyor; çoğu durumda 28 anlamlı hane — yazıya göre bazı durumlarda 29 — kullanılabiliyor. Sınır kesin: yirmi sekizinci anlamlı haneden sonrası ya yuvarlanıp atılmalı ya da reddedilmeli, varsayılan parse yolu ise yuvarlıyor. Crate'ın varsayılan yuvarlama modu half-even. from_str_exact aynı koşulu hataya çevirdiği için katı bir varyant mevcut, ancak varsayılan yolun Ok sonucunda hanelerin kaybolduğuna dair hiçbir ipucu yok.
Bu tür string'lerin doğduğu fiat/token uçurumu
Yazının daha geniş argümanı, alışılmış arama sonucu özeti olan — "sabit boyutlu ve hızlı ile sınırsız hassasiyet" — ifadesinin doğru olduğunu ama bir tip seçmek için yeterli olmadığı. Pratik dökümü şöyle:
- f64 herkesin ilk denediği testte başarısız oluyor: 0.1'i on kez toplamak 0.9999999999999999 veriyor ve 0.1 + 0.2 == 0.3 ifadesi false değerlendiriliyor.
- i64 minor unitler kesindir ve Stripe ile Adyen'in ağa koyduğu biçimdir; tek bir i64 pençe cinsinden 92,233,720,368,547,758.07 tutarını, wei cinsinden sayıldığında 9.223372036854775807 ETH tutarını taşır.
- i128/u128 minor unitler token bakiyelerini ve TigerBeetle tarzı defterleri yaklaşık 3,4 × 10³⁸'e kadar kapsıyor.
- rust_decimal oranlar, ücretler, vergi, FX ve API tutarları için uygun.
- bigdecimal — heap destekli bir BigInt, i64 scale ve sınırsız hassasiyetle — girdilerin 28 haneyi aşabileceği sınırlarda kullanılmaya layık.
Kesme örneği tam olarak o sınırda duruyor: on iki tam sayı hanesi olan bir tutar, 28 hanelik bütçe içinde yalnızca on altı kesirli haneye yer bırakıyor, buna karşın 18 ondalıklı token tutarları on sekiz ister.
Crate tablosunun geri kalanı
Yazı ayrıca fastnum 0.7.5'i de tabloluyor: 19, 38, 77 ve 154 hanelik sabit hassasiyet katmanları, varsayılan yuvarlama modu olarak half-up, NaN ve Infinity desteği ve string üreten ama yalnızca string kabul eden serde ayarları. rust_decimal ve bigdecimal ikisi de string'e serileştiriyor ve girdide string ya da sayı kabul ediyor. Postgres için rust_decimal sqlx, Diesel ve tokio-postgres destekliyor; bigdecimal sqlx ve Diesel'i kapsıyor; fastnum üçünü de kapsıyor. 3 Kasım 2026 itibarıyla yazı toplam indirme sayılarını rust_decimal için 169,1M, bigdecimal için 139,5M ve fastnum için 10,6M olarak listeliyor; en son sürümler sırasıyla 2 Eylül 2026, 28 Eylül 2026 ve 11 Haziran 2026 tarihlerinde, fastnum hâlâ 1.0 öncesinde.
Neden önemli
Tek amacı kesin para aritmetiği olan bir tipteki sessiz hassasiyet kaybı, mevcut en kötü hata modlarından birine yakın — çünkü parse anında görünmez. from_str ile bir yatırımı kaydeden bir defter, göndericinin aktardığından bir wei eksik saklar; hiçbir şey hata vermez ve tutarsızlık ancak daha sonra bir mutabakat kırığı olarak ortaya çıkar. Önlem ucuz ve yerel: güvenilmeyen veya zincirden gelen tutarları from_str_exact ile parse edin, bakiyeleri tam sayı minor unitlerde tutun ve girdilerin 28 haneyi aşabileceği uçlarda bigdecimal kullanın. Yazının daha derin noktası şu: "kesin ondalık" bir garanti değil, bir kapsam iddiasıdır — 28 hane fiat tutarlarını rahatça kapsıyor ama on iki hanelik tam sayı kısmı olan 18 ondalıklı bir token'ın kuyruğunu hâlâ kaybediyor.
- #rust
- #rust-decimal
- #bigdecimal
- #money
- #precision
- #fintech