Есть алгоритм, который считает токены.
Выглядит так:
User 1 закинул в котёл 100 монет А и 10 монет Б.
User 2 закинул в котёл 200 монет А и 20 монет Б.
Мы складываем все монеты и даём юзерам токены равные сумме этих монет
User 1 = 110 токенов
User 2 = 220 токенов
Общий котёл токенов = 330 токенов
Теперь нам надо высчитать, сколько user 1 имеет монет исходя из его токенов:
110 (токенов user 1) / 330 (все токены котла) = 0,33333333
Берём все монеты в котле и умножаем на 0,33333333
300 * 0,33333333 = 99.99999999
Получается 99.99999999
Ответ не совпадает, так как у user 1 было 100 монет, а получаем мы 99.99999999
Как решить эту задачу, чтобы ответ был точным, без использования функций округления, так как монеты могут быть в значении 0.0005, и округление сделает их нулём.
Есть пример на GOLang:
https://go.dev/play/p/6ycWbK1Dans
Код примераpackage main
import (
"fmt"
"github.com/shopspring/decimal"
)
func calculateCoins(userTokens, totalTokens, totalCoins decimal.Decimal) decimal.Decimal {
ratio := userTokens.Div(totalTokens)
userCoins := ratio.Mul(totalCoins)
return userCoins
}
func main() {
user1_CoinA := decimal.NewFromFloat(100)
user1_CoinB := decimal.NewFromFloat(10)
user2_CoinA := decimal.NewFromFloat(200)
user2_CoinB := decimal.NewFromFloat(20)
user1_Tokens := user1_CoinA.Add(user1_CoinB)
user2_Tokens := user2_CoinA.Add(user2_CoinB)
totalTokens := user1_Tokens.Add(user2_Tokens)
totalCoinsA := user1_CoinA.Add(user2_CoinA)
user1Coins := calculateCoins(user1_Tokens, totalTokens, totalCoinsA)
user2Coins := calculateCoins(user2_Tokens, totalTokens, totalCoinsA)
fmt.Println("User 1 has", user1Coins.String(), "coins")
fmt.Println("User 2 has", user2Coins.String(), "coins")
}