github.com/Anderson-Lu/gobox@v0.0.0-20191127065433-3e6c4c2da420/number/number_helper.go (about) 1 package number 2 3 import ( 4 "math" 5 "math/rand" 6 "strconv" 7 "strings" 8 ) 9 10 /* 11 * Return random int value between 0 and max-1 12 */ 13 func RandomInt(max int) int { 14 return rand.Intn(max) 15 } 16 17 /* 18 * Return the min value between a1 and a2 19 */ 20 func Min(a1, a2 float64) float64 { 21 if a1 < a2 { 22 return a1 23 } 24 return a2 25 } 26 27 /* 28 * Return the min value between a1 to aN 29 */ 30 func MinN(aN ...int) int { 31 ret := math.MaxInt16 32 for _, v := range aN { 33 if v < ret { 34 ret = v 35 } 36 } 37 return ret 38 } 39 40 /* 41 * Return the min value between a1 to aN 42 */ 43 func MinFloat64N(aN ...float64) float64 { 44 ret := math.MaxFloat64 45 for _, v := range aN { 46 if v < ret { 47 ret = v 48 } 49 } 50 return ret 51 } 52 53 //向上或者向下按照有效位数取整 54 //n为有效位数 55 //raw为原始数字 56 //isUp是否向上取整,否则为向下取整 57 func FloorOrCeil(n int, raw float64, isUp bool) float64 { 58 59 if raw >= math.Pow(10.0, float64(n)) { 60 return raw 61 } 62 63 t := strconv.FormatFloat(raw, 'G', n, 64) 64 ret, _ := strconv.ParseFloat(t, 64) 65 t1 := strconv.FormatFloat(raw, 'G', n+1, 64) 66 ret1, _ := strconv.ParseFloat(t1, 64) 67 pointIndex := strings.Index(t1, ".") 68 69 lastCh, _ := strconv.ParseInt(t1[len(t1)-1:], 10, 64) 70 isNotZero := (ret1-ret != 0) 71 72 if !isNotZero { 73 return ret 74 } 75 76 points := len(t1) - pointIndex - 1 77 78 //整数位数大于小数位数 79 if pointIndex > points && pointIndex == n && points != 1 { 80 81 if isUp && lastCh < 5 { 82 ret += 1.0 83 } 84 85 if isNotZero && lastCh >= 5 && !isUp && points != 0 { 86 ret -= 1.0 87 } 88 } else if pointIndex > points && pointIndex == n && points == 1 { 89 if lastCh <= 5 && isUp { 90 ret += 1.0 91 } 92 if lastCh > 5 && !isUp { 93 ret -= 1.0 94 } 95 } else { 96 97 fator := math.Pow(10, float64(-points+1)) 98 99 if isUp { 100 101 if isNotZero && lastCh < 5 { 102 ret += fator 103 } else if isNotZero && lastCh <= 5 && points == 2 { 104 ret += fator 105 } 106 } 107 108 if isNotZero && lastCh >= 5 && !isUp && points != 2 { 109 ret -= fator 110 } 111 } 112 113 tmp := strconv.FormatFloat(ret, 'G', n, 64) //3.3343 114 ret, _ = strconv.ParseFloat(tmp, 64) 115 return ret 116 } 117 118 //判断有多少位精度 119 func CalcDigist(n float64) int { 120 switch n { 121 case 0.1: 122 return 1 123 case 0.01: 124 return 2 125 case 0.001: 126 return 3 127 case 0.0001: 128 return 4 129 case 0.00001: 130 return 5 131 case 0.000001: 132 return 6 133 case 0.0000001: 134 return 7 135 case 0.00000001: 136 return 8 137 default: 138 return -1 139 } 140 } 141 142 //按照指定精度位数向上或者向下取整 143 func Round(f float64, n int) float64 { 144 var i int = 1 145 var count int = 0 146 for { 147 if int(f/float64(i)) > 0 { 148 i *= 10 149 count++ 150 continue 151 } 152 break 153 } 154 return FloorOrCeil(count+n, f, false) 155 } 156 157 func f(x, a float64) float64 { 158 return math.Exp(x) - a 159 } 160 161 func Ln(n float64) float64 { 162 var lo, hi, m float64 163 if n <= 0 { 164 return -1 165 } 166 if n == 1 { 167 return 0 168 } 169 EPS := 0.00001 170 lo = 0 171 hi = n 172 for math.Abs(lo-hi) >= EPS { 173 m = float64((lo + hi) / 2.0) 174 if f(m, n) < 0 { 175 lo = m 176 } else { 177 hi = m 178 } 179 } 180 return float64((lo + hi) / 2.0) 181 }