Rust akıllı sözleşmelerde sayısal işlem hassasiyeti sorunları ve optimizasyon çözümleri

robot
Abstract generation in progress

Rust akıllı sözleşmeler yetiştirme günlüğü (7) Ondalık ve tam sayı işlemleri hassasiyet sorunu

Bu yazıda Rust akıllı sözleşmelerindeki ondalık ve tam sayı işlemlerinin hassasiyet sorunları ile sayısal aktüerya akıllı sözleşmelerinin nasıl yazılacağı tartışılacaktır.

1. Kesirli sayıların hesaplama hassasiyeti sorunu

Rust dilinin yerel olarak ondalıklı sayı hesaplamalarını desteklemesine rağmen, ondalıklı sayı hesaplamalarının kaçınılmaz hesaplama hassasiyeti sorunları vardır. Akıllı sözleşmeler yazarken, özellikle önemli ekonomik/finansal kararların oranları veya faiz oranları ile ilgili hesaplamalarda ondalıklı sayı hesaplamalarının kullanılmasını önerilmez.

Rust dilinde kayan noktalı sayılar IEEE 754 standardını kullanır ve 2 tabanlı bilimsel notasyon ile temsil edilir. Bazı ondalık sayılar ( gibi 0.7), sınırlı uzunluktaki kayan nokta sayılarıyla kesin olarak temsil edilemez ve "yuvarlama" olayı yaşanabilir.

Örneğin, NEAR blok zincirinde 10 kullanıcıya 0.7 NEAR token dağıtıldığında:

pas #[test] fn precision_test_float() { let amount: f64 = 0.7;
let divisor: f64 = 10.0;
let result_0 = amount / divisor;
assert_eq!(result_0, 0.07, ""); }

İşlem sonuçları, amount'un değerinin tam olarak 0.7 olmadığını, bunun yerine yaklaşık değerinin 0.69999999999999995559 olduğunu gösteriyor. Bölme işleminin sonucu da kesin değil, beklenen 0.07 yerine 0.06999999999999999.

Bu sorunu çözmek için, sabit noktalı sayılar kullanmayı düşünebilirsiniz. NEAR Protokolü'nde genellikle 1 NEAR = 10^24 yoctoNEAR şeklinde ifade edilir:

pas #[test] fn precision_test_integer() { let N: u128 = 1_000_000_000_000_000_000_000_000;
let amount: u128 = 700_000_000_000_000_000_000_000; let divisor: u128 = 10;
let result_0 = amount / divisor; assert_eq!(result_0, 70_000_000_000_000_000_000_000, ""); }

Bu şekilde sayısal hesaplamanın sonucu elde edilebilir: 0.7 NEAR / 10 = 0.07 NEAR.

2. Rust tamsayı hesaplama hassasiyeti sorunu

2.1 İşlem Sırası

Aynı aritmetik önceliğe sahip çarpma ve bölme işlemlerinin sırası, hesaplama sonucunu doğrudan etkileyebilir:

pas #[test] fn precision_test_div_before_mul() { let a: u128 = 1_0000; let b: u128 = 10_0000; let c: u128 = 20;

let result_0 = a.checked_mul(c).expect("ERR_MUL")
                .checked_div(b).expect("ERR_DIV");

let result_1 = a.checked_div(b).expect("ERR_DIV")
                .checked_mul(c).expect("ERR_MUL");

assert_eq!(result_0,result_1,"");

}

İşlem sonucu, result_0 ve result_1'in eşit olmadığını gösteriyor. Bunun nedeni, tam sayı bölmesinin paydanın altındaki hassasiyeti atmasıdır. result_1'i hesaplarken, (a / b) önce hassasiyet kaybına uğrayarak 0'a dönüşür; oysa result_0'ı hesaplarken, a * c'nin hesaplanması hassasiyet kaybını önler.

2.2 çok küçük bir ölçek

Küçük ölçekler de hassasiyet sorunlarına yol açabilir:

pas #[test] fn precision_test_decimals() { let a: u128 = 10; let b: u128 = 3; let c: u128 = 4; let decimal: u128 = 100_0000;

let result_0 = a.checked_div(b).expect("ERR_DIV")
                .checked_mul(c).expect("ERR_MUL");

let result_1 = a.checked_mul(decimal).expect("ERR_MUL")
                .checked_div(b).expect("ERR_DIV")
                .checked_mul(c).expect("ERR_MUL")
                .checked_div(decimal).expect("ERR_DIV");

assert_eq!(result_0, result_1, "");

}

Sonuçlar gösteriyor ki result_0=12, result_1=13, ikincisi beklenen değer 13.3333'e daha yakın.

3. Sayısal Aktüerya için Rust akıllı sözleşmeler nasıl yazılır

Kesinliği artırmak için şu koruma önlemleri alınabilir:

3.1 İşlem sırasını ayarlama

Tam sayı çarpımının tam sayı bölümü öncelikli olması.

3.2 Tam sayıların büyüklüğünü artırma

Daha büyük bir ölçek kullanarak, daha büyük moleküller yaratın. Örneğin, 5.123 NEAR'ı 5.123 * 10^10 = 51_230_000_000 olarak gösterin.

3.3 Hesaplama hassasiyeti kaybı

Hesaplama hassasiyeti kaybının toplamını kaydet:

pas const USER_NUM: u128 = 3;

u128 { let dağıtılacak_token = offset + miktar; let per_user_share = token_to_distribute / USER_NUM; let recorded_offset = token_to_distribute - per_user_share * USER_NUM; kaydedilmiş_offset }

#( fn record_offset_test)[test] { let mut offset: u128 = 0; i için 1..7 { offset = distribute(to_yocto)"10"(, offset(; } }

Bu şekilde dağıtılmayan token'lar geçici olarak saklanabilir ve bir sonraki dağıtımda birlikte verilebilir.

) 3.4 Rust Crate kütüphanesi rust-decimal kullanımı

Bu kütüphane, etkili hassasiyet hesaplamaları ve yuvarlama hatası olmayan ondalık finansal hesaplamalar için uygundur.

) 3.5 Yuvarlama mekanizmasını dikkate alınız

Akıllı sözleşmeler tasarlandığında genellikle "Ben avantaj sağlamak istiyorum, başkaları benim yararım üzerinden kazanç elde edemez" ilkesi benimsenir. Duruma göre aşağı veya yukarı yuvarlama seçilir, nadiren en yakın tam sayıya yuvarlama yapılır.

![]###https://img-cdn.gateio.im/webp-social/moments-6e8b4081214a69423fc7ae022d05c728.webp###

View Original
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • Reward
  • 8
  • Share
Comment
0/400
SandwichHuntervip
· 07-16 18:07
rust küçük tavuk yine yere uzandı
View OriginalReply0
WhaleStalkervip
· 07-16 17:00
Kod hatası gerçekten can sıkıcı...
View OriginalReply0
GhostInTheChainvip
· 07-15 16:28
rust hala ondalık sayı girmesi gerekiyor... kolay değil
View OriginalReply0
BoredWatchervip
· 07-13 18:40
rust kütüphanesi sözleşme yazabilir mi?
View OriginalReply0
GasFeeNightmarevip
· 07-13 18:35
Hesaplama hassasiyeti, benim gas ücretim gibi sinir bozucu...
View OriginalReply0
EyeOfTheTokenStormvip
· 07-13 18:34
Hassasiyet kaybı oranı doğrudan kar-zarar oranını etkiler, kim hala ondalık sayılarla nicelik yapıyor? Kumarbazlar çoktan Rug Pull yaptı değil mi?
View OriginalReply0
TokenEconomistvip
· 07-13 18:32
aslında, hassasiyet kaybı = f(emir_ops, ölçek_faktörü) ... rust-decimal kütüphanesi harika
View OriginalReply0
just_another_walletvip
· 07-13 18:25
Kayan nokta sayısı çok sıkıntılı değil mi...
View OriginalReply0
Trade Crypto Anywhere Anytime
qrCode
Scan to download Gate app
Community
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)