github.com/searKing/golang/go@v1.2.117/format/multiple_prefix/binary_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 // 计量单位,如Ki、Mi、Gi、Ti 15 type BinaryMultiplePrefix struct { 16 multiplePrefix 17 } 18 19 // https://physics.nist.gov/cuu/Units/binary.html 20 // 21 // Prefixes for binary multiples 22 // Factor Name Symbol Origin Derivation 23 // 210 kibi Ki kilobinary: (2^10)^1 kilo: (10^3)^1 24 // 220 mebi Mi megabinary: (2^10)^2 mega: (10^3)^2 25 // 230 gibi Gi gigabinary: (2^10)^3 giga: (10^3)^3 26 // 240 tebi Ti terabinary: (2^10)^4 tera: (10^3)^4 27 // 250 pebi Pi petabinary: (2^10)^5 peta: (10^3)^5 28 // 260 exbi Ei exabinary: (2^10)^6 exa: (10^3)^6 29 var ( 30 BinaryMultiplePrefixMin = BinaryMultiplePrefixOne 31 BinaryMultiplePrefixOne = BinaryMultiplePrefix{multiplePrefix{2, 0, "", ""}} // BaseNumber^0 10^0 32 BinaryMultiplePrefixKibi = BinaryMultiplePrefix{multiplePrefix{2, 10, "kibi", "Ki"}} // BaseNumber^1 10^+03 33 BinaryMultiplePrefixMebi = BinaryMultiplePrefix{multiplePrefix{2, 20, "mebi", "Mi"}} // BaseNumber^2 10^+06 34 BinaryMultiplePrefixGibi = BinaryMultiplePrefix{multiplePrefix{2, 30, "gibi", "Gi"}} // BaseNumber^3 10^+09 35 BinaryMultiplePrefixTebi = BinaryMultiplePrefix{multiplePrefix{2, 40, "tebi", "Ti"}} // BaseNumber^4 10^+12 36 BinaryMultiplePrefixPebi = BinaryMultiplePrefix{multiplePrefix{2, 50, "pebi", "Pi"}} // BaseNumber^5 10^+15 37 BinaryMultiplePrefixExbi = BinaryMultiplePrefix{multiplePrefix{2, 60, "exbi", "Ei"}} // BaseNumber^6 10^+18 38 BinaryMultiplePrefixMax = BinaryMultiplePrefixExbi 39 ) 40 41 var ( 42 BinaryMultiplePrefixTODO = BinaryMultiplePrefix{multiplePrefix{base: 2}} 43 ) 44 var binaryNegativeMultiplePrefixes = [...]BinaryMultiplePrefix{} 45 var binaryZeroMultiplePrefixes = [...]BinaryMultiplePrefix{BinaryMultiplePrefixOne} 46 var binaryPositiveMultiplePrefixes = [...]BinaryMultiplePrefix{BinaryMultiplePrefixKibi, BinaryMultiplePrefixMebi, BinaryMultiplePrefixGibi, BinaryMultiplePrefixTebi, BinaryMultiplePrefixPebi, BinaryMultiplePrefixExbi} 47 48 func (dp BinaryMultiplePrefix) Copy() *BinaryMultiplePrefix { 49 var dp2 = &BinaryMultiplePrefix{} 50 *dp2 = dp 51 return dp2 52 } 53 54 // number 123kb 55 // symbolOrName is k or kilo 56 func (dp *BinaryMultiplePrefix) SetPrefix(symbolOrName string) *BinaryMultiplePrefix { 57 for _, prefix := range binaryPositiveMultiplePrefixes { 58 if prefix.matched(symbolOrName) { 59 *dp = prefix 60 return dp 61 } 62 } 63 *dp = BinaryMultiplePrefixOne 64 return dp 65 } 66 67 // number 1000000 => power 6 => prefix M 68 func (dp *BinaryMultiplePrefix) SetPower(power int) *BinaryMultiplePrefix { 69 if power == 0 { 70 *dp = BinaryMultiplePrefixOne 71 return dp 72 } 73 if power > 0 { 74 for _, prefix := range binaryPositiveMultiplePrefixes { 75 if prefix.power == power { 76 *dp = prefix 77 return dp 78 } 79 } 80 *dp = BinaryMultiplePrefixOne 81 return dp 82 } 83 *dp = BinaryMultiplePrefixOne 84 return dp 85 } 86 87 // number 1000000 => power 6 => prefix M 88 func (dp *BinaryMultiplePrefix) SetUint64(num uint64) *BinaryMultiplePrefix { 89 return dp.SetFloat64(float64(num)) 90 } 91 92 func (dp *BinaryMultiplePrefix) SetInt64(num int64) *BinaryMultiplePrefix { 93 if num >= 0 { 94 return dp.SetUint64(uint64(num)) 95 } 96 return dp.SetUint64(uint64(-num)) 97 } 98 99 func (dp *BinaryMultiplePrefix) SetFloat64(num float64) *BinaryMultiplePrefix { 100 if math_.Close(num, 0) { 101 *dp = BinaryMultiplePrefixOne 102 return dp 103 } 104 num = math.Abs(num) 105 if num > math.MaxUint64 { 106 *dp = BinaryMultiplePrefixMax 107 return dp 108 } 109 110 numPower := math.Log10(num) / math.Log10(float64(dp.Base())) 111 if math_.Close(numPower, 0) { 112 *dp = BinaryMultiplePrefixOne 113 return dp 114 } 115 if numPower > 0 { 116 // 幂 117 if numPower >= float64(BinaryMultiplePrefixMax.power) { 118 *dp = BinaryMultiplePrefixMax 119 return dp 120 } 121 lastPrefix := BinaryMultiplePrefixOne 122 for _, prefix := range binaryPositiveMultiplePrefixes { 123 if numPower < float64(prefix.power) { 124 *dp = lastPrefix 125 return dp 126 } 127 lastPrefix = prefix 128 } 129 130 *dp = BinaryMultiplePrefixMax 131 return dp 132 } 133 if numPower <= float64(BinaryMultiplePrefixMin.power) { 134 *dp = BinaryMultiplePrefixMin 135 return dp 136 } 137 138 *dp = BinaryMultiplePrefixMin 139 return dp 140 } 141 142 func (dp *BinaryMultiplePrefix) SetBigFloat(num *big.Float) *BinaryMultiplePrefix { 143 num.Abs(num) 144 145 if num.Cmp(big.NewFloat(math.MaxFloat64)) <= 0 { 146 f64, _ := num.Float64() 147 return dp.SetFloat64(f64) 148 } 149 150 *dp = BinaryMultiplePrefixMax 151 return dp 152 } 153 154 func (dp *BinaryMultiplePrefix) SetBigInt(num *big.Int) *BinaryMultiplePrefix { 155 var numFloat big.Float 156 numFloat.SetInt(num) 157 return dp.SetBigFloat(&numFloat) 158 } 159 160 func (dp *BinaryMultiplePrefix) SetBigRat(num *big.Rat) *BinaryMultiplePrefix { 161 var numFloat big.Float 162 numFloat.SetRat(num) 163 return dp.SetBigFloat(&numFloat) 164 }