github.com/yaoapp/kun@v0.9.0/num/number.go (about) 1 package num 2 3 import ( 4 "database/sql/driver" 5 "encoding/json" 6 "fmt" 7 "regexp" 8 "strconv" 9 ) 10 11 // Number type of numberic 12 type Number struct { 13 value interface{} 14 } 15 16 // Make create a empty instance 17 func Make() *Number { 18 return &Number{value: nil} 19 } 20 21 // Of make a new number 22 func Of(value interface{}) *Number { 23 return &Number{value: value} 24 } 25 26 // Set set <value> to <v>, and returns the old value. 27 func (n *Number) Set(value interface{}) (old interface{}) { 28 old = n.value 29 n.value = value 30 return old 31 } 32 33 // ToFixed the return value is the type of float64 and keeps the given decimal places 34 func (n Number) ToFixed(places int) string { 35 format := fmt.Sprintf("%%.%df", places) 36 return fmt.Sprintf(format, n.Float64()) 37 } 38 39 // Float is alias of Float64 converts and returns as float64 40 func (n Number) Float() float64 { 41 return n.Float64() 42 } 43 44 // Float64 converts and returns as float64 45 func (n Number) Float64() float64 { 46 if n.value == nil { 47 return 0.0 48 } 49 50 switch n.value.(type) { 51 case float64: 52 return n.value.(float64) 53 case float32: 54 return float64(n.value.(float32)) 55 case complex128: 56 return real(n.value.(complex128)) 57 case complex64: 58 return float64(real(n.value.(complex64))) 59 } 60 61 value, err := strconv.ParseFloat(fmt.Sprintf("%v", n.value), 64) 62 if err != nil { 63 panic(err.Error()) 64 } 65 return value 66 } 67 68 // Float32 converts and returns as float32 69 func (n Number) Float32() float32 { 70 if n.value == nil { 71 return 0.0 72 } 73 74 switch n.value.(type) { 75 case float64: 76 return float32(n.value.(float64)) 77 case float32: 78 return n.value.(float32) 79 } 80 81 value, err := strconv.ParseFloat(fmt.Sprintf("%v", n.value), 32) 82 if err != nil { 83 panic(err.Error()) 84 } 85 return float32(value) 86 } 87 88 // Complex is alias of Complex128 converts and returns as complex128 89 func (n Number) Complex() complex128 { 90 return n.Complex128() 91 } 92 93 // Complex128 converts and returns as complex128 94 func (n Number) Complex128() complex128 { 95 value, ok := n.value.(complex128) 96 if ok { 97 return value 98 } 99 100 value64, ok := n.value.(complex64) 101 if ok { 102 return complex128(value64) 103 } 104 105 valueStr, ok := n.value.(string) 106 if ok { 107 // 1.56+2.48i 108 re := regexp.MustCompile(`[ \()]*([0-9\.]+)[ ]*\+[ ]*([0-9\.]+)i[ \)]*`) 109 matched := re.FindStringSubmatch(valueStr) 110 if len(matched) > 0 { 111 return complex(Of(matched[1]).Float64(), Of(matched[2]).Float64()) 112 } 113 114 // (1.56,2.48i) 115 re = regexp.MustCompile(`\([ ]*([0-9\.]+)[ ]*,[ ]*([0-9\.]+)[ ]*\)`) 116 matched = re.FindStringSubmatch(valueStr) 117 if len(matched) > 0 { 118 return complex(Of(matched[1]).Float64(), Of(matched[2]).Float64()) 119 } 120 } 121 return complex(n.Float64(), 0) 122 } 123 124 // Complex64 converts and returns as Complex64 125 func (n Number) Complex64() complex64 { 126 value, ok := n.value.(complex64) 127 if ok { 128 return value 129 } 130 131 value128, ok := n.value.(complex128) 132 if ok { 133 return complex64(value128) 134 } 135 136 valueStr, ok := n.value.(string) 137 if ok { 138 // 1.56+2.48i 139 re := regexp.MustCompile(`[ \()]*([0-9\.]+)[ ]*\+[ ]*([0-9\.]+)i[ \)]*`) 140 matched := re.FindStringSubmatch(valueStr) 141 if len(matched) > 0 { 142 return complex(Of(matched[1]).Float32(), Of(matched[2]).Float32()) 143 } 144 145 // (1.56,2.48i) 146 re = regexp.MustCompile(`\([ ]*([0-9\.]+)[ ]*,[ ]*([0-9\.]+)[ ]*\)`) 147 matched = re.FindStringSubmatch(valueStr) 148 if len(matched) > 0 { 149 return complex(Of(matched[1]).Float32(), Of(matched[2]).Float32()) 150 } 151 } 152 return complex(n.Float32(), 0.0) 153 } 154 155 // Int64 the return value is the type of int64 and remove the decimal 156 func (n Number) Int64() int64 { 157 value, ok := n.value.(int64) 158 if ok { 159 return value 160 } 161 return int64(n.Int()) 162 } 163 164 // Int32 the return value is the type of int32 and remove the decimal 165 func (n Number) Int32() int32 { 166 value, ok := n.value.(int32) 167 if ok { 168 return value 169 } 170 return int32(n.Int()) 171 } 172 173 // Int16 the return value is the type of int16 and remove the decimal 174 func (n Number) Int16() int16 { 175 value, ok := n.value.(int16) 176 if ok { 177 return value 178 } 179 return int16(n.Int()) 180 } 181 182 // Int8 converts and returns as Int8 183 func (n Number) Int8() int8 { 184 value, ok := n.value.(int8) 185 if ok { 186 return value 187 } 188 return int8(n.Int()) 189 } 190 191 // Int converts and returns as Int 192 func (n Number) Int() int { 193 if n.value == nil { 194 return 0 195 } 196 197 value, ok := n.value.(int) 198 if ok { 199 return value 200 } 201 202 value, _ = strconv.Atoi(fmt.Sprintf("%.0f", n.Float64())) 203 return value 204 } 205 206 // Uint64 the return value is the type of uint64 and remove the decimal 207 func (n Number) Uint64() uint64 { 208 value, ok := n.value.(uint64) 209 if ok { 210 return value 211 } 212 return uint64(n.Int()) 213 } 214 215 // Uint32 the return value is the type of uint32 and remove the decimal 216 func (n Number) Uint32() uint32 { 217 value, ok := n.value.(uint32) 218 if ok { 219 return value 220 } 221 return uint32(n.Int()) 222 } 223 224 // Uint16 the return value is the type of uint16 and remove the decimal 225 func (n Number) Uint16() uint16 { 226 value, ok := n.value.(uint16) 227 if ok { 228 return value 229 } 230 return uint16(n.Int()) 231 } 232 233 // Uint8 the return value is the type of uint8 and remove the decimal 234 func (n Number) Uint8() uint8 { 235 value, ok := n.value.(uint8) 236 if ok { 237 return value 238 } 239 return uint8(n.Int()) 240 } 241 242 // Uint the return value is the type of uint and remove the decimal 243 func (n Number) Uint() uint { 244 value, ok := n.value.(uint) 245 if ok { 246 return value 247 } 248 return uint(n.Int()) 249 } 250 251 // Uintptr the return value is the type of uintptr 252 func (n Number) Uintptr() uintptr { 253 value, ok := n.value.(uintptr) 254 if ok { 255 return value 256 } 257 return uintptr(n.Int()) 258 } 259 260 // IsSet checks whether <v> is not nil. 261 func (n Number) IsSet() bool { 262 return n.value != nil 263 } 264 265 // IsNil checks whether <v> is nil. 266 func (n Number) IsNil() bool { 267 return n.value == nil 268 } 269 270 // IsInt checks whether <v> is type of int. 271 func (n Number) IsInt() bool { 272 switch n.value.(type) { 273 case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: 274 return true 275 default: 276 return false 277 } 278 } 279 280 // IsFloat checks whether <v> is type of float. 281 func (n Number) IsFloat() bool { 282 switch n.value.(type) { 283 case float32, float64: 284 return true 285 default: 286 return false 287 } 288 } 289 290 // IsComplex checks whether <v> is type of complex. 291 func (n Number) IsComplex() bool { 292 switch n.value.(type) { 293 case complex128, complex64: 294 return true 295 default: 296 return false 297 } 298 } 299 300 // Scan for db scan 301 func (n *Number) Scan(src interface{}) error { 302 *n = *Of(src) 303 return nil 304 } 305 306 // Value for db driver value 307 func (n *Number) Value() (driver.Value, error) { 308 return n.value, nil 309 } 310 311 // MarshalJSON for json marshalJSON 312 func (n *Number) MarshalJSON() ([]byte, error) { 313 return json.Marshal(n.value) 314 } 315 316 // UnmarshalJSON for json marshalJSON 317 func (n *Number) UnmarshalJSON(data []byte) error { 318 var v float64 319 err := json.Unmarshal(data, &v) 320 if err != nil { 321 return err 322 } 323 *n = *Of(v) 324 return nil 325 }