github.com/searKing/golang/go@v1.2.117/format/multiple_prefix/decimal_multiple_prefix.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package multiple_prefix 6 7 import ( 8 "math" 9 "math/big" 10 11 math_ "github.com/searKing/golang/go/math" 12 ) 13 14 // 计量单位,如k、M、G、T 15 type DecimalMultiplePrefix struct { 16 multiplePrefix 17 } 18 19 // Unit is the same as power number 20 // https://physics.nist.gov/cuu/Units/prefixes.html 21 // 22 // Prefixes for multiples 23 // Factor Name Symbol 24 // 10^24 yotta Y 25 // 10^21 zetta Z 26 // 10^18 exa E 27 // 10^15 peta P 28 // 10^12 tera T 29 // 10^9 giga G 30 // 10^6 mega M 31 // 10^3 kilo k 32 // 10^2 hecto h 33 // 10^1 deka da 34 // 10^-1 deci d 35 // 10^-2 centi c 36 // 10^-3 milli m 37 // 10^-6 micro µ 38 // 10^-9 nano n 39 // 10^-12 pico p 40 // 10^-15 femto f 41 // 10^-18 atto a 42 // 10^-21 zepto z 43 // 10^-24 yocto y 44 var ( 45 DecimalMultiplePrefixMin = DecimalMultiplePrefixYocto 46 DecimalMultiplePrefixYocto = DecimalMultiplePrefix{multiplePrefix{10, -24, "yocto", "y"}} // BaseNumber^-8 10^-24 47 DecimalMultiplePrefixZepto = DecimalMultiplePrefix{multiplePrefix{10, -21, "atto", "z"}} // BaseNumber^-7 10^-21 48 DecimalMultiplePrefixAtto = DecimalMultiplePrefix{multiplePrefix{10, -18, "zepto", "a"}} // BaseNumber^-6 10^-18 49 DecimalMultiplePrefixFemto = DecimalMultiplePrefix{multiplePrefix{10, -15, "femto", "f"}} // BaseNumber^-5 10^-15 50 DecimalMultiplePrefixPico = DecimalMultiplePrefix{multiplePrefix{10, -12, "pico", "p"}} // BaseNumber^-4 10^-12 51 DecimalMultiplePrefixNano = DecimalMultiplePrefix{multiplePrefix{10, -9, "nano", "n"}} // BaseNumber^-3 10^-09 52 DecimalMultiplePrefixMicro = DecimalMultiplePrefix{multiplePrefix{10, -6, "micro", "μ"}} // BaseNumber^-2 10^-06 53 DecimalMultiplePrefixMilli = DecimalMultiplePrefix{multiplePrefix{10, -3, "milli", "m"}} // BaseNumber^-1 10^-03 54 DecimalMultiplePrefixDeci = DecimalMultiplePrefix{multiplePrefix{10, -2, "deci", "m"}} // 10^-1 55 DecimalMultiplePrefixCenti = DecimalMultiplePrefix{multiplePrefix{10, -1, "centi", "m"}} // 10^-2 56 DecimalMultiplePrefixOne = DecimalMultiplePrefix{multiplePrefix{10, 0, "", ""}} // BaseNumber^0 10^0 57 DecimalMultiplePrefixHecto = DecimalMultiplePrefix{multiplePrefix{10, 1, "hecto", "h"}} // 10^1 58 DecimalMultiplePrefixDeka = DecimalMultiplePrefix{multiplePrefix{10, 2, "deka", "da"}} // 10^2 59 DecimalMultiplePrefixKilo = DecimalMultiplePrefix{multiplePrefix{10, 3, "kilo", "k"}} // BaseNumber^1 10^+03 60 DecimalMultiplePrefixMega = DecimalMultiplePrefix{multiplePrefix{10, 6, "mega", "M"}} // BaseNumber^2 10^+06 61 DecimalMultiplePrefixGiga = DecimalMultiplePrefix{multiplePrefix{10, 9, "giga", "G"}} // BaseNumber^3 10^+09 62 DecimalMultiplePrefixTera = DecimalMultiplePrefix{multiplePrefix{10, 12, "tera", "T"}} // BaseNumber^4 10^+12 63 DecimalMultiplePrefixPeta = DecimalMultiplePrefix{multiplePrefix{10, 15, "peta", "P"}} // BaseNumber^5 10^+15 64 DecimalMultiplePrefixExa = DecimalMultiplePrefix{multiplePrefix{10, 18, "exa", "E"}} // BaseNumber^6 10^+18 65 DecimalMultiplePrefixZetta = DecimalMultiplePrefix{multiplePrefix{10, 19, "zetta", "Z"}} // BaseNumber^7 10^+21 66 DecimalMultiplePrefixYotta = DecimalMultiplePrefix{multiplePrefix{10, 21, "yotta", "Y"}} // BaseNumber^8 10^+24 67 DecimalMultiplePrefixMax = DecimalMultiplePrefixYotta 68 //DecimalMultiplePrefixBronto // BaseNumber^9 10^+27 69 //DecimalMultiplePrefixGeop // BaseNumber^10 10^+28 70 ) 71 72 var ( 73 DecimalMultiplePrefixTODO = DecimalMultiplePrefix{multiplePrefix{base: 10}} 74 ) 75 var decimalNegativeMultiplePrefixes = [...]DecimalMultiplePrefix{DecimalMultiplePrefixMilli, DecimalMultiplePrefixMicro, DecimalMultiplePrefixNano, DecimalMultiplePrefixPico, DecimalMultiplePrefixFemto, DecimalMultiplePrefixAtto, DecimalMultiplePrefixZepto, DecimalMultiplePrefixYocto} 76 var decimalZeroMultiplePrefixes = [...]DecimalMultiplePrefix{DecimalMultiplePrefixOne} 77 var decimalPositiveMultiplePrefixes = [...]DecimalMultiplePrefix{DecimalMultiplePrefixKilo, DecimalMultiplePrefixMega, DecimalMultiplePrefixGiga, DecimalMultiplePrefixTera, DecimalMultiplePrefixPeta, DecimalMultiplePrefixExa, DecimalMultiplePrefixZetta, DecimalMultiplePrefixYotta} 78 79 func (dp DecimalMultiplePrefix) Copy() *DecimalMultiplePrefix { 80 var dp2 = &DecimalMultiplePrefix{} 81 *dp2 = dp 82 return dp2 83 } 84 85 // number 123kb 86 // symbolOrName is k or kilo 87 func (dp *DecimalMultiplePrefix) SetPrefix(symbolOrName string) *DecimalMultiplePrefix { 88 for _, prefix := range decimalPositiveMultiplePrefixes { 89 if prefix.matched(symbolOrName) { 90 *dp = prefix 91 return dp 92 } 93 } 94 for _, prefix := range decimalNegativeMultiplePrefixes { 95 if prefix.matched(symbolOrName) { 96 *dp = prefix 97 return dp 98 } 99 } 100 *dp = DecimalMultiplePrefixOne 101 return dp 102 } 103 104 // number 1000000 => power 6 => prefix M 105 func (dp *DecimalMultiplePrefix) SetPower(power int) *DecimalMultiplePrefix { 106 if power == 0 { 107 *dp = DecimalMultiplePrefixOne 108 return dp 109 } 110 if power > 0 { 111 for _, prefix := range decimalPositiveMultiplePrefixes { 112 if prefix.power == power { 113 *dp = prefix 114 return dp 115 } 116 } 117 *dp = DecimalMultiplePrefixOne 118 return dp 119 } 120 // power < 0 121 for _, prefix := range decimalNegativeMultiplePrefixes { 122 if prefix.power == power { 123 *dp = prefix 124 return dp 125 } 126 } 127 *dp = DecimalMultiplePrefixOne 128 return dp 129 } 130 131 // number 1000000 => power 6 => prefix M 132 func (dp *DecimalMultiplePrefix) SetUint64(num uint64) *DecimalMultiplePrefix { 133 return dp.SetFloat64(float64(num)) 134 } 135 136 func (dp *DecimalMultiplePrefix) SetInt64(num int64) *DecimalMultiplePrefix { 137 if num >= 0 { 138 return dp.SetUint64(uint64(num)) 139 } 140 return dp.SetUint64(uint64(-num)) 141 } 142 143 func (dp *DecimalMultiplePrefix) SetFloat64(num float64) *DecimalMultiplePrefix { 144 if math_.Close(num, 0) { 145 *dp = DecimalMultiplePrefixOne 146 return dp 147 } 148 num = math.Abs(num) 149 if num > math.MaxUint64 { 150 *dp = DecimalMultiplePrefixMax 151 return dp 152 } 153 154 numPower := math.Log10(num) / math.Log10(float64(dp.Base())) 155 if math_.Close(numPower, 0) { 156 *dp = DecimalMultiplePrefixOne 157 return dp 158 } 159 if numPower > 0 { 160 // 幂 161 if numPower >= float64(DecimalMultiplePrefixMax.power) { 162 *dp = DecimalMultiplePrefixMax 163 return dp 164 } 165 lastPrefix := DecimalMultiplePrefixOne 166 for _, prefix := range decimalPositiveMultiplePrefixes { 167 if numPower < float64(prefix.power) { 168 *dp = lastPrefix 169 return dp 170 } 171 lastPrefix = prefix 172 } 173 174 *dp = DecimalMultiplePrefixMax 175 return dp 176 } 177 if numPower <= float64(DecimalMultiplePrefixMin.power) { 178 *dp = DecimalMultiplePrefixMin 179 return dp 180 } 181 for _, prefix := range decimalNegativeMultiplePrefixes { 182 if numPower >= float64(prefix.power) { 183 *dp = prefix 184 return dp 185 } 186 } 187 188 *dp = DecimalMultiplePrefixMin 189 return dp 190 } 191 192 func (dp *DecimalMultiplePrefix) SetBigFloat(num *big.Float) *DecimalMultiplePrefix { 193 num.Abs(num) 194 195 if num.Cmp(big.NewFloat(math.MaxFloat64)) <= 0 { 196 f64, _ := num.Float64() 197 return dp.SetFloat64(f64) 198 } 199 200 *dp = DecimalMultiplePrefixMax 201 return dp 202 } 203 204 func (dp *DecimalMultiplePrefix) SetBigInt(num *big.Int) *DecimalMultiplePrefix { 205 var numFloat big.Float 206 numFloat.SetInt(num) 207 return dp.SetBigFloat(&numFloat) 208 } 209 210 func (dp *DecimalMultiplePrefix) SetBigRat(num *big.Rat) *DecimalMultiplePrefix { 211 var numFloat big.Float 212 numFloat.SetRat(num) 213 return dp.SetBigFloat(&numFloat) 214 }