Rust akıllı sözleşmeler geliştirme: Sayısal hesaplama ve hassasiyet kontrolü teknikleri

Rust akıllı sözleşmeler yetiştirme günlüğü (7): Sayısal hesaplama

1. Kesirli sayıların hesaplama hassasiyeti sorunu

Rust dili yerel olarak ondalık sayı işlemlerini destekler, ancak ondalık sayı işlemlerinde kaçınılmaz hesaplama hassasiyeti sorunları vardır. Akıllı sözleşmeler yazarken, özellikle önemli ekonomik/finansal kararlarla ilgili oranlar veya faiz oranları işlenirken ondalık sayı işlemleri kullanılması önerilmez.

Rust dilindeki çift hassasiyetli kayan nokta türü f64, IEEE 754 standardını takip eder ve taban 2 bilimsel gösterim kullanır. Bazı ondalık sayılar, örneğin 0.7, sınırlı uzunluktaki kayan nokta sayılarıyla doğru bir şekilde ifade edilemez ve "yuvarlama" olayı vardır.

NEAR blok zincirinde on kullanıcıya 0.7 NEAR token dağıtma testinde, ondalık hesaplama sonuçları kesin değil:

pas let amount: f64 = 0.7;
let divisor: f64 = 10.0; let result_0 = amount / divisor;

amount'ın değeri 0.69999999999999995559, result_0'ın değeri ise 0.06999999999999999, beklenen 0.07 değil.

Bu sorunu çözmek için, sabit nokta kullanabilirsiniz. NEAR Protocol'de genellikle 1 NEAR = 10^24 yoctoNEAR şeklinde ifade edilir:

pas 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;

Bu şekilde kesin bir hesaplama sonucu elde edilebilir: 0.7 NEAR / 10 = 0.07 NEAR.

2. Rust tam sayı hesaplama hassasiyeti sorunu

2.1 İşlem Sırası

Aynı aritmetik önceliğe sahip çarpma ve bölmenin, önceden ve sonradan sırasının değişmesi hesaplama sonucunu doğrudan etkileyebilir. Örneğin:

pas let a: u128 = 1_0000; let b: u128 = 10_0000; let c: u128 = 20;

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

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

result_0 ve result_1'in hesaplama sonuçları farklıdır, çünkü tam sayı bölme için, paydanın altında kalan hassasiyet atılacaktır.

2.2 çok küçük bir büyüklük

Küçük değerler söz konusu olduğunda, tam sayı işlemleri hassasiyet kaybına neden olabilir:

pas let a: u128 = 10; let b: u128 = 3; let c: u128 = 4; let decimal: u128 = 100_0000;

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

// result_1 = (a * ondalık / b) * c / ondalık; 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");

result_0 ve result_1'in hesaplama sonuçları farklıdır, result_1 gerçek beklenen değere daha yakındır.

3. Sayısal Actuarial Rust akıllı sözleşmeler nasıl yazılır

3.1 İşlem sırasını ayarlama

Tam sayı çarpımının tam sayı bölmeden önce gelmesini sağlar.

3.2 tam sayının büyüklüğünü artırmak

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

3.3 Birikim işlemleri doğruluğunun kaybı

Kayıtlı toplam hesaplama hassasiyet kaybını, sonraki işlemlerde telafi etme. Örneğin:

pas u128 { let token_to_distribute = offset + amount; let per_user_share = token_to_distribute / USER_NUM; let recorded_offset = token_to_distribute - per_user_share * USER_NUM; kaydedilen_ofset }

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

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

) 3.5 Yuvarlama mekanizmasını dikkate alın

Akıllı sözleşmeler tasarımında, yuvarlama problemi genellikle "Ben kar elde etmeliyim, başkaları benim kazancımı almamalı" ilkesine dayanır. Duruma göre aşağı yuvarlama, yukarı yuvarlama veya en yakın tam sayıya yuvarlama seçilir.

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

TOKEN-9.95%
NUM-3.18%
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
  • 3
  • Share
Comment
0/400
BearMarketBuildervip
· 18h ago
Kayan nokta bu çukur deniz gibi derin.
View OriginalReply0
SelfSovereignStevevip
· 18h ago
Kayan nokta sayıları çok sorunlu, akıllı sözleşmeler kesinlikle patlayacak, tamamen kullanmaya cesaret edemiyorum.
View OriginalReply0
DegenGamblervip
· 18h ago
Rust ile uğraşan kardeşler dikkat etsin, hassasiyet bu çukur küçük değil.
View OriginalReply0
  • Pin
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)