Files

42 lines
1.1 KiB
Go

package kernel
import (
"errors"
"math/big"
)
var (
ErrInvalidTokenBilling = errors.New("按量计费参数无效")
ErrTokenBillingOverflow = errors.New("按量计费金额超出上限")
)
type TokenBillingTerm struct {
Tokens int64
PriceMicrocredits int64
}
// TokenBillingAmount 按每百万 Token 单价及万分比倍率汇总费用,只对最终微积分金额上取整。
func TokenBillingAmount(multiplierBPS int64, terms ...TokenBillingTerm) (int64, error) {
if multiplierBPS <= 0 {
return 0, ErrInvalidTokenBilling
}
var total, product big.Int
for _, term := range terms {
if term.Tokens < 0 || term.PriceMicrocredits < 0 {
return 0, ErrInvalidTokenBilling
}
product.Mul(big.NewInt(term.Tokens), big.NewInt(term.PriceMicrocredits))
total.Add(&total, &product)
}
total.Mul(&total, big.NewInt(multiplierBPS))
var remainder big.Int
total.QuoRem(&total, big.NewInt(10_000_000_000), &remainder)
if remainder.Sign() != 0 {
total.Add(&total, big.NewInt(1))
}
if !total.IsInt64() {
return 0, ErrTokenBillingOverflow
}
return total.Int64(), nil
}