|
|
package decimal
|
|
|
|
|
|
import (
|
|
|
"github.com/shopspring/decimal"
|
|
|
)
|
|
|
|
|
|
// Percent2PointMax9999 百分额,保留2位小数,如果分母为0 ,最大返回9999%
|
|
|
func Percent2PointMax9999(numerator, denominator int64) string {
|
|
|
zero, ok := DenZero(numerator, denominator, 9999)
|
|
|
if ok {
|
|
|
return zero.StringFixedBank(2)
|
|
|
}
|
|
|
|
|
|
val := Percent(numerator, denominator)
|
|
|
fnum := val.InexactFloat64()
|
|
|
if fnum > 0 && fnum < 0.01 {
|
|
|
return "0.01"
|
|
|
}
|
|
|
|
|
|
return val.StringFixedBank(2)
|
|
|
}
|
|
|
|
|
|
// Chain1PointMax999 环比,保留1位小数据,如果分母为0 ,最大返回999%
|
|
|
func Chain1PointMax999(numerator, denominator int64) (int32, string) {
|
|
|
if numerator == 0 {
|
|
|
return 0, "0"
|
|
|
}
|
|
|
|
|
|
zero, ok := DenZero(numerator, denominator, 999)
|
|
|
if ok {
|
|
|
return 1, zero.StringFixed(1)
|
|
|
}
|
|
|
|
|
|
var status int32
|
|
|
|
|
|
val := Chain(numerator, denominator).Mul(decimal.NewFromFloat(100))
|
|
|
|
|
|
fnum := val.InexactFloat64()
|
|
|
if fnum < 0 {
|
|
|
status = 2
|
|
|
} else if fnum > 0 {
|
|
|
status = 1
|
|
|
}
|
|
|
|
|
|
val = val.Abs()
|
|
|
|
|
|
fnum = val.InexactFloat64()
|
|
|
if fnum > 0 && fnum < 0.1 {
|
|
|
return status, "0.1"
|
|
|
}
|
|
|
|
|
|
return status, val.StringFixed(1)
|
|
|
}
|
|
|
|
|
|
// Percent2PointMap 百分额hash表,保证计算合计100%
|
|
|
func Percent2PointMap(children []*Operator, denominator int64) OperatorMap {
|
|
|
om := make(OperatorMap, len(children))
|
|
|
|
|
|
var oc []*Operator
|
|
|
for _, child := range children {
|
|
|
if child.Num == 0 || denominator == 0 {
|
|
|
om[child.Id] = "0.00"
|
|
|
} else {
|
|
|
oc = append(oc, child)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
lid := len(oc)
|
|
|
if lid > 1 {
|
|
|
var zero = decimal.Zero
|
|
|
var dec = make(map[int64]decimal.Decimal)
|
|
|
var maxChild = decimal.Zero
|
|
|
var maxIdx int64
|
|
|
for _, child := range oc {
|
|
|
val := Percent(child.Num, denominator)
|
|
|
if val.InexactFloat64() < 0.01 {
|
|
|
val = decimal.NewFromFloat(0.01)
|
|
|
}
|
|
|
|
|
|
// 只要小数后两位
|
|
|
val = val.RoundBank(2)
|
|
|
|
|
|
if val.GreaterThan(maxChild) {
|
|
|
maxChild = val
|
|
|
maxIdx = child.Id
|
|
|
}
|
|
|
|
|
|
dec[child.Id] = val
|
|
|
zero = zero.Add(val)
|
|
|
}
|
|
|
|
|
|
var hundred = decimal.NewFromFloat(100)
|
|
|
|
|
|
if zero.GreaterThan(hundred) {
|
|
|
dec[maxIdx] = dec[maxIdx].Sub(zero.Sub(hundred))
|
|
|
} else if zero.LessThan(hundred) {
|
|
|
dec[maxIdx] = dec[maxIdx].Add(hundred.Sub(zero))
|
|
|
}
|
|
|
|
|
|
for id, v := range dec {
|
|
|
om[id] = v.StringFixedBank(2)
|
|
|
}
|
|
|
} else if lid == 1 {
|
|
|
om[oc[0].Id] = "100.00"
|
|
|
}
|
|
|
|
|
|
return om
|
|
|
}
|