初始化项目
This commit is contained in:
4
trunk/goutil/mathUtil/doc.go
Normal file
4
trunk/goutil/mathUtil/doc.go
Normal file
@@ -0,0 +1,4 @@
|
||||
/*
|
||||
数学助手包,提供一些与数学相关的助手方法
|
||||
*/
|
||||
package mathUtil
|
||||
5
trunk/goutil/mathUtil/iWeight.go
Normal file
5
trunk/goutil/mathUtil/iWeight.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package mathUtil
|
||||
|
||||
type IWeight interface {
|
||||
GetWeight() int
|
||||
}
|
||||
33
trunk/goutil/mathUtil/intRegion.go
Normal file
33
trunk/goutil/mathUtil/intRegion.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// int类型区间对象,表示连续的int类型区间
|
||||
type IntRegion struct {
|
||||
Lower int
|
||||
Upper int
|
||||
}
|
||||
|
||||
func (this *IntRegion) String() string {
|
||||
return fmt.Sprintf("%d-%d", this.Lower, this.Upper)
|
||||
}
|
||||
|
||||
// 是否包含指定的值
|
||||
func (this *IntRegion) Contains(value int) bool {
|
||||
return this.Lower <= value && value <= this.Upper
|
||||
}
|
||||
|
||||
// 是否是有序的
|
||||
func (this *IntRegion) IsSorted() bool {
|
||||
return this.Lower < this.Upper
|
||||
}
|
||||
|
||||
// 创建int类型区间对象
|
||||
func NewIntRegion(lower, upper int) *IntRegion {
|
||||
return &IntRegion{
|
||||
Lower: lower,
|
||||
Upper: upper,
|
||||
}
|
||||
}
|
||||
186
trunk/goutil/mathUtil/math.go
Normal file
186
trunk/goutil/mathUtil/math.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// 判断传入的byte型数组是否连续
|
||||
func IsContinuous_byte(list []byte) bool {
|
||||
if len(list) == 0 || len(list) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
list_int64 := make([]int64, len(list), len(list))
|
||||
for i, v := range list {
|
||||
list_int64[i] = int64(v)
|
||||
}
|
||||
|
||||
return IsContinuous_int64(list_int64)
|
||||
}
|
||||
|
||||
// 判断传入的int型数组是否连续
|
||||
func IsContinuous_int(list []int) bool {
|
||||
if len(list) == 0 || len(list) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
list_int64 := make([]int64, len(list), len(list))
|
||||
for i, v := range list {
|
||||
list_int64[i] = int64(v)
|
||||
}
|
||||
|
||||
return IsContinuous_int64(list_int64)
|
||||
}
|
||||
|
||||
// 判断传入的int型数组是否连续
|
||||
func IsContinuous_int32(list []int32) bool {
|
||||
if len(list) == 0 || len(list) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
list_int64 := make([]int64, len(list), len(list))
|
||||
for i, v := range list {
|
||||
list_int64[i] = int64(v)
|
||||
}
|
||||
|
||||
return IsContinuous_int64(list_int64)
|
||||
}
|
||||
|
||||
// 判断传入的int型数组是否连续
|
||||
func IsContinuous_int64(list []int64) bool {
|
||||
if len(list) == 0 || len(list) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
if int64(len(list)) != list[len(list)-1]-list[0]+1 {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(list)-1; i++ {
|
||||
if list[i]+1 != list[i+1] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 判断区间是否连续
|
||||
func IsContinuous_Region(list []*IntRegion) bool {
|
||||
if len(list) == 0 || len(list) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
sort.Slice(list, func(i, j int) bool { return list[i].Lower < list[j].Lower })
|
||||
|
||||
for i := 0; i < len(list)-1; i++ {
|
||||
if list[i].IsSorted() == false || list[i+1].IsSorted() == false {
|
||||
return false
|
||||
}
|
||||
|
||||
if list[i].Upper+1 != list[i+1].Lower {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 判断传入的概率是否全覆盖
|
||||
func IsOddFullConvered(list []*IntRegion, min, max int) bool {
|
||||
if len(list) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if list[0].Lower != min || list[len(list)-1].Upper != max {
|
||||
return false
|
||||
}
|
||||
|
||||
sort.Slice(list, func(i, j int) bool { return list[i].Lower < list[j].Lower })
|
||||
|
||||
for i := 0; i < len(list)-1; i++ {
|
||||
if list[i].IsSorted() == false || list[i+1].IsSorted() == false {
|
||||
return false
|
||||
}
|
||||
|
||||
if list[i].Upper+1 != list[i+1].Lower {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func IsDistinct_byte(list []byte) (result bool) {
|
||||
if len(list) == 0 || len(list) == 1 {
|
||||
result = true
|
||||
return
|
||||
}
|
||||
|
||||
list_int64 := make([]int64, len(list), len(list))
|
||||
for i, v := range list {
|
||||
list_int64[i] = int64(v)
|
||||
}
|
||||
|
||||
return IsDistinct_int64(list_int64)
|
||||
}
|
||||
|
||||
func IsDistinct_int(list []int) (result bool) {
|
||||
if len(list) == 0 || len(list) == 1 {
|
||||
result = true
|
||||
return
|
||||
}
|
||||
|
||||
list_int64 := make([]int64, len(list), len(list))
|
||||
for i, v := range list {
|
||||
list_int64[i] = int64(v)
|
||||
}
|
||||
|
||||
return IsDistinct_int64(list_int64)
|
||||
}
|
||||
|
||||
func IsDistinct_int32(list []int32) (result bool) {
|
||||
if len(list) == 0 || len(list) == 1 {
|
||||
result = true
|
||||
return
|
||||
}
|
||||
|
||||
list_int64 := make([]int64, len(list), len(list))
|
||||
for i, v := range list {
|
||||
list_int64[i] = int64(v)
|
||||
}
|
||||
|
||||
return IsDistinct_int64(list_int64)
|
||||
}
|
||||
|
||||
// 判断int64数组是否内容唯一
|
||||
func IsDistinct_int64(list []int64) (result bool) {
|
||||
if len(list) == 0 || len(list) == 1 {
|
||||
result = true
|
||||
return
|
||||
}
|
||||
|
||||
sort.Slice(list, func(i, j int) bool { return list[i] < list[j] })
|
||||
|
||||
for i := 0; i < len(list)-1; i++ {
|
||||
if list[i] == list[i+1] {
|
||||
result = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
result = true
|
||||
return
|
||||
}
|
||||
|
||||
//// 将int转成uint类型(因goutil指定go版本过低,不支持泛型,未实际加入;要使用的人取消注释,并指定允许泛型的go版本)
|
||||
//// 应用场景:atomic.AddUint64 想减1时
|
||||
////
|
||||
//// x := uint64(1000)
|
||||
//// y := int64(-1)
|
||||
//// atomic.AddUint64(&x, intToUint[int64, uint64](y))
|
||||
//func intToUint[T1 int8 | int16 | int32 | int64 | int, T2 uint8 | uint16 | uint32 | uint64 | uint](x T1) T2 {
|
||||
// // 写到函数内,两种方式都可以;若直接使用,只能使用^T2(-x - 1);若使用T2(x)方式,x为负值时转为uint类语法检查无法通过
|
||||
// return ^T2(-x - 1)
|
||||
// // return T2(x)
|
||||
//}
|
||||
267
trunk/goutil/mathUtil/math_test.go
Normal file
267
trunk/goutil/mathUtil/math_test.go
Normal file
@@ -0,0 +1,267 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsContinuous_byte(t *testing.T) {
|
||||
list := make([]byte, 0, 8)
|
||||
if IsContinuous_byte(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, 1)
|
||||
if IsContinuous_byte(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------2")
|
||||
}
|
||||
|
||||
list = append(list, 2)
|
||||
list = append(list, 3)
|
||||
list = append(list, 4)
|
||||
list = append(list, 5)
|
||||
if IsContinuous_byte(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------3")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
if IsContinuous_byte(list) == true {
|
||||
t.Errorf("it's should be false, but now true-------3")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsContinuous_int(t *testing.T) {
|
||||
list := make([]int, 0, 8)
|
||||
if IsContinuous_int(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, 11)
|
||||
if IsContinuous_int(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------2")
|
||||
}
|
||||
|
||||
list = append(list, 12)
|
||||
list = append(list, 13)
|
||||
list = append(list, 14)
|
||||
list = append(list, 15)
|
||||
if IsContinuous_int(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------3")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
if IsContinuous_int(list) == true {
|
||||
t.Errorf("it's should be false, but now true-------3")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsContinuous_int32(t *testing.T) {
|
||||
list := make([]int32, 0, 8)
|
||||
if IsContinuous_int32(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, 1)
|
||||
if IsContinuous_int32(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------2")
|
||||
}
|
||||
|
||||
list = append(list, 2)
|
||||
list = append(list, 3)
|
||||
list = append(list, 4)
|
||||
list = append(list, 5)
|
||||
if IsContinuous_int32(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------3")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
if IsContinuous_int32(list) == true {
|
||||
t.Errorf("it's should be false, but now true-------3")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsContinuous_int64(t *testing.T) {
|
||||
list := make([]int64, 0, 8)
|
||||
if IsContinuous_int64(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, 1)
|
||||
if IsContinuous_int64(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------2")
|
||||
}
|
||||
|
||||
list = append(list, 2)
|
||||
list = append(list, 3)
|
||||
list = append(list, 4)
|
||||
list = append(list, 5)
|
||||
if IsContinuous_int64(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------3")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
if IsContinuous_int64(list) == true {
|
||||
t.Errorf("it's should be false, but now true-------3")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsContinuous_Region(t *testing.T) {
|
||||
list := make([]*IntRegion, 0, 8)
|
||||
if IsContinuous_Region(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, NewIntRegion(101, 110))
|
||||
if IsContinuous_Region(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, NewIntRegion(1, 10))
|
||||
if IsContinuous_Region(list) == true {
|
||||
t.Errorf("it's should be false, but now true-------2")
|
||||
}
|
||||
|
||||
list = append(list, NewIntRegion(11, 100))
|
||||
if IsContinuous_Region(list) == false {
|
||||
t.Errorf("it's should be true, but now false-------3")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestIsOddFullConvered(t *testing.T) {
|
||||
list := make([]*IntRegion, 0, 8)
|
||||
min, max := 1, 100
|
||||
if IsOddFullConvered(list, min, max) {
|
||||
t.Errorf("it's should be false, but now true-------1")
|
||||
}
|
||||
|
||||
list = append(list, NewIntRegion(1, 10))
|
||||
if IsOddFullConvered(list, min, max) == true {
|
||||
t.Errorf("it's should be false, but now true-------2")
|
||||
}
|
||||
|
||||
list = append(list, NewIntRegion(11, 100))
|
||||
if IsOddFullConvered(list, min, max) == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDistinct_byte(t *testing.T) {
|
||||
list := make([]byte, 0, 8)
|
||||
result := IsDistinct_byte(list)
|
||||
fmt.Printf("list:%v,result:%v-------1\n", list, result)
|
||||
if result == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
result = IsDistinct_byte(list)
|
||||
fmt.Printf("list:%v,result:%v-------2\n", list, result)
|
||||
if result == false {
|
||||
t.Errorf("it's should be true, but now false-------2")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
result = IsDistinct_byte(list)
|
||||
fmt.Printf("list:%v,result:%v-------3\n", list, result)
|
||||
if result {
|
||||
t.Errorf("it's should be false, but now true-------3")
|
||||
}
|
||||
|
||||
list = append(list, 0)
|
||||
result = IsDistinct_byte(list)
|
||||
fmt.Printf("list:%v,result:%v-------4\n", list, result)
|
||||
if result {
|
||||
t.Errorf("it's should be false, but now true-------4")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDistinct_int(t *testing.T) {
|
||||
list := make([]int, 0, 8)
|
||||
result := IsDistinct_int(list)
|
||||
fmt.Printf("list:%v,result:%v-------1\n", list, result)
|
||||
if result == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
result = IsDistinct_int(list)
|
||||
fmt.Printf("list:%v,result:%v-------2\n", list, result)
|
||||
if result == false {
|
||||
t.Errorf("it's should be true, but now false-------2")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
result = IsDistinct_int(list)
|
||||
fmt.Printf("list:%v,result:%v-------3\n", list, result)
|
||||
if result {
|
||||
t.Errorf("it's should be false, but now true-------3")
|
||||
}
|
||||
|
||||
list = append(list, 0)
|
||||
result = IsDistinct_int(list)
|
||||
fmt.Printf("list:%v,result:%v-------4\n", list, result)
|
||||
if result {
|
||||
t.Errorf("it's should be false, but now true-------4")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDistinct_int32(t *testing.T) {
|
||||
list := make([]int32, 0, 8)
|
||||
result := IsDistinct_int32(list)
|
||||
fmt.Printf("list:%v,result:%v-------1\n", list, result)
|
||||
if result == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
result = IsDistinct_int32(list)
|
||||
fmt.Printf("list:%v,result:%v-------2\n", list, result)
|
||||
if result == false {
|
||||
t.Errorf("it's should be true, but now false-------2")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
result = IsDistinct_int32(list)
|
||||
fmt.Printf("list:%v,result:%v-------3\n", list, result)
|
||||
if result {
|
||||
t.Errorf("it's should be false, but now true-------3")
|
||||
}
|
||||
|
||||
list = append(list, 0)
|
||||
result = IsDistinct_int32(list)
|
||||
fmt.Printf("list:%v,result:%v-------4\n", list, result)
|
||||
if result {
|
||||
t.Errorf("it's should be false, but now true-------4")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDistinct_int64(t *testing.T) {
|
||||
list := make([]int64, 0, 8)
|
||||
result := IsDistinct_int64(list)
|
||||
fmt.Printf("list:%v,result:%v-------1\n", list, result)
|
||||
if result == false {
|
||||
t.Errorf("it's should be true, but now false-------1")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
result = IsDistinct_int64(list)
|
||||
fmt.Printf("list:%v,result:%v-------2\n", list, result)
|
||||
if result == false {
|
||||
t.Errorf("it's should be true, but now false-------2")
|
||||
}
|
||||
|
||||
list = append(list, 10)
|
||||
result = IsDistinct_int64(list)
|
||||
fmt.Printf("list:%v,result:%v-------3\n", list, result)
|
||||
if result {
|
||||
t.Errorf("it's should be false, but now true-------3")
|
||||
}
|
||||
|
||||
list = append(list, 0)
|
||||
result = IsDistinct_int64(list)
|
||||
fmt.Printf("list:%v,result:%v-------4\n", list, result)
|
||||
if result {
|
||||
t.Errorf("it's should be false, but now true-------4")
|
||||
}
|
||||
}
|
||||
130
trunk/goutil/mathUtil/quartile.go
Normal file
130
trunk/goutil/mathUtil/quartile.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"sort"
|
||||
)
|
||||
|
||||
//同时计算上中下四分位数
|
||||
func Quartile_Int(intList []int) (lowerquartile, midquartile, upperquartile float64, err error) {
|
||||
n := len(intList)
|
||||
|
||||
if n == 0 {
|
||||
err = errors.New("List is empty")
|
||||
return
|
||||
}
|
||||
|
||||
//长度大于等于2的情况
|
||||
//排序 升序
|
||||
sort.Ints(intList)
|
||||
lowerquartile, err = Quartile_Int_Lower(intList, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
midquartile, err = Quartile_Int_Mid(intList, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
upperquartile, err = Quartile_Int_Upper(intList, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 计算整数数组下四分为数据
|
||||
func Quartile_Int_Lower(intList []int, isSorted bool) (lowerquartile float64, err error) {
|
||||
n := len(intList)
|
||||
|
||||
if n == 0 {
|
||||
err = errors.New("List is empty")
|
||||
return
|
||||
}
|
||||
//如果长度为1,则上、中、下四分为数都等于该值
|
||||
if n == 1 {
|
||||
lowerquartile = float64(intList[0])
|
||||
return
|
||||
}
|
||||
//长度大于等于2的情况
|
||||
//排序 升序 ,如果数据没有排序,则排序
|
||||
if !isSorted {
|
||||
sort.Ints(intList)
|
||||
}
|
||||
//计算下四分位数位置
|
||||
lowerPosition := 1 + float64(n-1)*0.25
|
||||
intPart, deciPart := math.Modf(lowerPosition)
|
||||
//将整数部分转换为int类型,成为取数据的索引
|
||||
index := int(intPart)
|
||||
if index < 1 || index > n-1 {
|
||||
err = errors.New("Quartile_Int_Lower Index Out of Range")
|
||||
return
|
||||
}
|
||||
lowerquartile = float64(intList[index-1])*(1-deciPart) + float64(intList[index])*deciPart
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 计算整数数组中四分为数据
|
||||
func Quartile_Int_Mid(intList []int, isSorted bool) (midquartile float64, err error) {
|
||||
n := len(intList)
|
||||
|
||||
if n == 0 {
|
||||
err = errors.New("List is empty")
|
||||
return
|
||||
}
|
||||
//如果长度为1,则上、中、下四分为数都等于该值
|
||||
if n == 1 {
|
||||
midquartile = float64(intList[0])
|
||||
return
|
||||
}
|
||||
//长度大于等于2的情况
|
||||
//排序 升序 ,如果数据没有排序,则排序
|
||||
if !isSorted {
|
||||
sort.Ints(intList)
|
||||
}
|
||||
//计算下四分位数位置
|
||||
lowerPosition := 1 + float64(n-1)*0.5
|
||||
intPart, deciPart := math.Modf(lowerPosition)
|
||||
//将整数部分转换为int类型,成为取数据的索引
|
||||
index := int(intPart)
|
||||
if index < 1 || index > n-1 {
|
||||
err = errors.New("Quartile_Int_Mid Index Out of Range")
|
||||
return
|
||||
}
|
||||
midquartile = float64(intList[index-1])*(1-deciPart) + float64(intList[index])*deciPart
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 计算整数数组上四分为数据
|
||||
func Quartile_Int_Upper(intList []int, isSorted bool) (upperquartile float64, err error) {
|
||||
n := len(intList)
|
||||
|
||||
if n == 0 {
|
||||
err = errors.New("List is empty")
|
||||
return
|
||||
}
|
||||
//如果长度为1,则上、中、下四分为数都等于该值
|
||||
if n == 1 {
|
||||
upperquartile = float64(intList[0])
|
||||
return
|
||||
}
|
||||
//长度大于等于2的情况
|
||||
//排序 升序 ,如果数据没有排序,则排序
|
||||
if !isSorted {
|
||||
sort.Ints(intList)
|
||||
}
|
||||
//计算下四分位数位置
|
||||
lowerPosition := 1 + float64(n-1)*0.75
|
||||
intPart, deciPart := math.Modf(lowerPosition)
|
||||
//将整数部分转换为int类型,成为取数据的索引
|
||||
index := int(intPart)
|
||||
if index < 1 || index > n-1 {
|
||||
err = errors.New("Quartile_Int_Upper Index Out of Range")
|
||||
return
|
||||
}
|
||||
upperquartile = float64(intList[index-1])*(1-deciPart) + float64(intList[index])*deciPart
|
||||
|
||||
return
|
||||
}
|
||||
53
trunk/goutil/mathUtil/quartile_test.go
Normal file
53
trunk/goutil/mathUtil/quartile_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestQuartile(t *testing.T) {
|
||||
|
||||
intList := []int{}
|
||||
var lower, mid, upper float64
|
||||
var err error
|
||||
lower, mid, upper, err = Quartile_Int(intList)
|
||||
if err != nil {
|
||||
fmt.Printf("Error:%s\n", err)
|
||||
}
|
||||
|
||||
intList = []int{4}
|
||||
lower, mid, upper, err = Quartile_Int(intList)
|
||||
if err != nil {
|
||||
fmt.Printf("Error:%s\n", err)
|
||||
}
|
||||
fmt.Printf("LowerQuartile:%f\n", lower)
|
||||
fmt.Printf("MidQuartile:%f\n", mid)
|
||||
fmt.Printf("UpperQuartile:%f\n", upper)
|
||||
|
||||
intList = []int{4, 93}
|
||||
lower, mid, upper, err = Quartile_Int(intList)
|
||||
if err != nil {
|
||||
fmt.Printf("Error:%s\n", err)
|
||||
}
|
||||
fmt.Printf("LowerQuartile:%f\n", lower)
|
||||
fmt.Printf("MidQuartile:%f\n", mid)
|
||||
fmt.Printf("UpperQuartile:%f\n", upper)
|
||||
|
||||
intList = []int{4, 93, 84}
|
||||
lower, mid, upper, err = Quartile_Int(intList)
|
||||
if err != nil {
|
||||
fmt.Printf("Error:%s\n", err)
|
||||
}
|
||||
fmt.Printf("LowerQuartile:%f\n", lower)
|
||||
fmt.Printf("MidQuartile:%f\n", mid)
|
||||
fmt.Printf("UpperQuartile:%f\n", upper)
|
||||
|
||||
intList = []int{4, 93, 84, 85, 80, 37, 81, 93, 27, 12}
|
||||
lower, mid, upper, err = Quartile_Int(intList)
|
||||
if err != nil {
|
||||
fmt.Printf("Error:%s\n", err)
|
||||
}
|
||||
fmt.Printf("LowerQuartile:%f\n", lower)
|
||||
fmt.Printf("MidQuartile:%f\n", mid)
|
||||
fmt.Printf("UpperQuartile:%f\n", upper)
|
||||
}
|
||||
479
trunk/goutil/mathUtil/rand.go
Normal file
479
trunk/goutil/mathUtil/rand.go
Normal file
@@ -0,0 +1,479 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Rand struct {
|
||||
*rand.Rand
|
||||
}
|
||||
|
||||
type weightRand struct {
|
||||
index int
|
||||
weight int
|
||||
}
|
||||
|
||||
// 获得Rand对象(如果是循环生成多个数据,则只需要调用本方法一次,而不能调用多次,否则会得到相同的随机值)
|
||||
func GetRand() *Rand {
|
||||
return &Rand{
|
||||
Rand: rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
}
|
||||
}
|
||||
|
||||
func GetRandInSeed(seed int64) *Rand {
|
||||
return &Rand{
|
||||
Rand: rand.New(rand.NewSource(seed)),
|
||||
}
|
||||
}
|
||||
|
||||
// 获取指定区间的随机数[lower, upper)
|
||||
// lower:区间下限
|
||||
// upper:区间上限
|
||||
// 返回值:随机数
|
||||
func (this *Rand) GetRandRangeInt(lower, upper int) int {
|
||||
return lower + this.Intn(upper-lower)
|
||||
}
|
||||
|
||||
// 获取指定区间的随机数[lower, upper)
|
||||
// lower:区间下限
|
||||
// upper:区间上限
|
||||
// 返回值:随机数
|
||||
func (this *Rand) GetRandRangeInt32(lower, upper int32) int32 {
|
||||
return lower + this.Int31n(upper-lower)
|
||||
}
|
||||
|
||||
// 获取指定区间的随机数[lower, upper)
|
||||
// lower:区间下限
|
||||
// upper:区间上限
|
||||
// 返回值:随机数
|
||||
func (this *Rand) GetRandRangeInt64(lower, upper int64) int64 {
|
||||
return lower + this.Int63n(upper-lower)
|
||||
}
|
||||
|
||||
// 获取随机数[0, n)
|
||||
// randObj:随机对象
|
||||
// n:范围上限
|
||||
// 返回值:随机数
|
||||
func (this *Rand) GetRandInt(n int) int {
|
||||
return this.Intn(n)
|
||||
}
|
||||
|
||||
// 获取随机数[0, n)
|
||||
// n:范围上限
|
||||
// 返回值:随机数
|
||||
func (this *Rand) GetRandInt32(n int32) int32 {
|
||||
return this.Int31n(n)
|
||||
}
|
||||
|
||||
// 获取随机数[0, n)
|
||||
// randObj:随机对象
|
||||
// n:范围上限
|
||||
// 返回值:随机数
|
||||
func (this *Rand) GetRandInt64(n int64) int64 {
|
||||
return this.Int63n(n)
|
||||
}
|
||||
|
||||
// 获取随机数[0, 1)
|
||||
// randObj:随机对象
|
||||
// 返回值:随机数
|
||||
func (this *Rand) GetRandFloat32() float32 {
|
||||
return this.Float32()
|
||||
}
|
||||
|
||||
// 获取随机数[0, 1)
|
||||
// 返回值:随机数
|
||||
func (this *Rand) GetRandFloat64() float64 {
|
||||
return this.Float64()
|
||||
}
|
||||
|
||||
// 获取随机数列表(取值范围:[minValue, maxValue],注意:maxValue-minValue < 10000,区间大小超过10000会抛出异常)
|
||||
// minValue:获取随机数的区间下限值
|
||||
// maxValue:获取随机数的区间上限值
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *Rand) GetRandNumList(minValue, maxValue, count int, ifAllowDuplicate bool) ([]int, error) {
|
||||
if minValue > maxValue {
|
||||
return nil, errors.New("minValue can't be bigger than maxValue.")
|
||||
}
|
||||
|
||||
if !ifAllowDuplicate && (maxValue-minValue+1) < count {
|
||||
return nil, errors.New("随机的数量超过区间的元素数量")
|
||||
}
|
||||
|
||||
if (maxValue - minValue + 1) > 10000 {
|
||||
return nil, errors.New("随机数的区间不能大于10000")
|
||||
}
|
||||
|
||||
// 定义原始数据
|
||||
sourceCount := maxValue - minValue + 1
|
||||
source := make([]int, sourceCount, sourceCount)
|
||||
for index := 0; index < sourceCount; index++ {
|
||||
source[index] = minValue + index
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]int, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的int列表
|
||||
// source:源列表
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *Rand) GetRandIntList(source []int, count int, ifAllowDuplicate bool) ([]int, error) {
|
||||
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
|
||||
if ifAllowDuplicate == false && len(source) < count {
|
||||
return nil, errors.New("随机的数量超过列表的元素数量")
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]int, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的int32列表
|
||||
// source:源列表
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *Rand) GetRandInt32List(source []int32, count int, ifAllowDuplicate bool) ([]int32, error) {
|
||||
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
|
||||
if ifAllowDuplicate == false && len(source) < count {
|
||||
return nil, errors.New("随机的数量超过列表的元素数量")
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]int32, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的int64列表
|
||||
// source:源列表
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *Rand) GetRandInt64List(source []int64, count int, ifAllowDuplicate bool) ([]int64, error) {
|
||||
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
|
||||
if ifAllowDuplicate == false && len(source) < count {
|
||||
return nil, errors.New("随机的数量超过列表的元素数量")
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]int64, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的int64列表
|
||||
// source:源列表
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *Rand) GetRandStringList(source []string, count int, ifAllowDuplicate bool) ([]string, error) {
|
||||
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
|
||||
if ifAllowDuplicate == false && len(source) < count {
|
||||
return nil, errors.New("随机的数量超过列表的元素数量")
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]string, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的interface{}列表
|
||||
// source:源列表
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *Rand) GetRandInterfaceList(source []interface{}, count int, ifAllowDuplicate bool) ([]interface{}, error) {
|
||||
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
|
||||
if ifAllowDuplicate == false && len(source) < count {
|
||||
return nil, errors.New("随机的数量超过列表的元素数量")
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]interface{}, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的索引列表
|
||||
// count:数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机索引值列表
|
||||
func (this *Rand) getRandIndexList(maxNum, count int, ifAllowDuplicate bool) []int {
|
||||
// 定义返回值
|
||||
randIndextList := make([]int, 0, count)
|
||||
|
||||
// 使用源列表的数据量来初始化一个仅存放索引值的数组
|
||||
indexList := make([]int, maxNum, maxNum)
|
||||
for index := 0; index < maxNum; index++ {
|
||||
indexList[index] = index
|
||||
}
|
||||
|
||||
// 遍历列表并获取随机对象(通过不断缩小随机的范围来实现)
|
||||
maxIndex := len(indexList) - 1
|
||||
for {
|
||||
if len(randIndextList) < count {
|
||||
// 获取随机索引(由于Next方法不取上限值,所以需要maxIndex+1)
|
||||
randIndex := this.Intn(maxIndex + 1)
|
||||
|
||||
// 将数据添加到列表,并增加findCount
|
||||
randIndextList = append(randIndextList, indexList[randIndex])
|
||||
|
||||
// 如果不允许重复,则需要特殊处理
|
||||
if !ifAllowDuplicate {
|
||||
// 将该位置的数据和最大位置的数据进行交换
|
||||
indexList[randIndex], indexList[maxIndex] = indexList[maxIndex], indexList[randIndex]
|
||||
|
||||
// 将随机的范围缩小
|
||||
maxIndex -= 1
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return randIndextList
|
||||
}
|
||||
|
||||
// 获取带权重的随机数据
|
||||
// source:源数据
|
||||
// 返回值
|
||||
// 数据项
|
||||
// 错误对象
|
||||
func (this *Rand) GetRandWeight(source []IWeight) (result IWeight, err error) {
|
||||
if source == nil || len(source) == 0 {
|
||||
err = errors.New("待随机的列表为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 计算出总的数据量,并随机一个[0, total)的值
|
||||
total := 0
|
||||
for _, item := range source {
|
||||
total += item.GetWeight()
|
||||
}
|
||||
|
||||
randNum := this.GetRandInt(total)
|
||||
|
||||
// 根据随机出来的值,判断位于哪个区间
|
||||
total = 0
|
||||
for _, item := range source {
|
||||
total += item.GetWeight()
|
||||
if randNum < total {
|
||||
result = item
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = errors.New("未找到有效的数据")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取带权重的随机数据
|
||||
// source:源数据
|
||||
// count:返回数量
|
||||
// ifAllowDuplicate:返回索引中是否允许包含重复项
|
||||
// 返回值
|
||||
// 数据项的索引
|
||||
// 错误对象
|
||||
func (this *Rand) GetRandItemsByWeight(source []IWeight, count int, ifAllowDuplicate bool) ([]int, error) {
|
||||
var err error
|
||||
if source == nil || len(source) == 0 {
|
||||
err = errors.New("待随机的列表为空")
|
||||
return nil, err
|
||||
}
|
||||
if count <= 0 {
|
||||
err = errors.New("count 必须大于0")
|
||||
return nil, err
|
||||
}
|
||||
var lenCount int = len(source)
|
||||
if lenCount < count && ifAllowDuplicate == false {
|
||||
err = errors.New("source长度小于count,并且设定为不可重复,请修复")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 准备数据
|
||||
total := 0
|
||||
weightList := make([]*weightRand, 0, lenCount)
|
||||
for i, item := range source {
|
||||
tempWeight := item.GetWeight()
|
||||
weightList = append(weightList, &weightRand{index: i, weight: tempWeight})
|
||||
total = total + tempWeight
|
||||
}
|
||||
|
||||
if lenCount <= count {
|
||||
return this.countLessThanRand(count, total, weightList), nil
|
||||
}
|
||||
|
||||
return this.countIsGreaterThanRand(count, total, weightList), nil
|
||||
}
|
||||
|
||||
// 获取带权重的随机数据(列表元素数量<=需要的数量)
|
||||
// count:需要数量
|
||||
// total:总权重
|
||||
// weightList:权重列表
|
||||
// 返回值
|
||||
// 数据项的索引
|
||||
func (this *Rand) countLessThanRand(count, total int, weightList []*weightRand) []int {
|
||||
// 先所有的加入进去
|
||||
result := make([]int, 0, count)
|
||||
for k := range weightList {
|
||||
result = append(result, k)
|
||||
}
|
||||
|
||||
// 不删除随机
|
||||
tempCount := len(result)
|
||||
if tempCount >= count {
|
||||
return result
|
||||
}
|
||||
|
||||
for i := 0; i < count-tempCount; i++ {
|
||||
tempk := -1
|
||||
tempTotal := 0
|
||||
tempRandNum := this.GetRandInt(total + 1)
|
||||
for _, w := range weightList {
|
||||
tempTotal = tempTotal + w.weight
|
||||
if tempTotal > tempRandNum {
|
||||
break
|
||||
}
|
||||
|
||||
tempk = w.index
|
||||
}
|
||||
|
||||
// 如果未找到,则取第一个
|
||||
if tempk == -1 {
|
||||
tempk = weightList[0].index
|
||||
}
|
||||
|
||||
result = append(result, tempk)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// 获取带权重的随机数据(列表元素数量>需要的数量)
|
||||
// count:需要数量
|
||||
// total:总权重
|
||||
// weightList:权重列表
|
||||
// 返回值
|
||||
// 数据项的索引
|
||||
func (this *Rand) countIsGreaterThanRand(count, total int, weightList []*weightRand) []int {
|
||||
// 真随机+删除
|
||||
result := make([]int, 0, count)
|
||||
for j := 0; j < count; j++ {
|
||||
tempTotal := 0
|
||||
ri := -1
|
||||
var tw *weightRand
|
||||
tempRandNum := this.GetRandInt(total)
|
||||
for i, v := range weightList {
|
||||
tempTotal = tempTotal + v.weight
|
||||
if tempTotal > tempRandNum {
|
||||
break
|
||||
}
|
||||
tw = v
|
||||
ri = i
|
||||
}
|
||||
|
||||
// 如果未找到,则取第一个
|
||||
if tw == nil {
|
||||
tw = weightList[0]
|
||||
ri = 0
|
||||
}
|
||||
|
||||
result = append(result, tw.index)
|
||||
total = total - tw.weight
|
||||
|
||||
// 删除已经随机过的item
|
||||
weightList = append(weightList[:ri], weightList[ri+1:]...)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
325
trunk/goutil/mathUtil/rand_test.go
Normal file
325
trunk/goutil/mathUtil/rand_test.go
Normal file
@@ -0,0 +1,325 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetRandRangeInt(t *testing.T) {
|
||||
lower, upper := 10, 100
|
||||
rand := GetRand().GetRandRangeInt(lower, upper)
|
||||
if rand < lower || rand >= upper {
|
||||
t.Errorf("Expected a num between %d and %d, but got %d", lower, upper, rand)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRandInt(t *testing.T) {
|
||||
var n int = 100
|
||||
var rand int = GetRand().GetRandInt(n)
|
||||
if rand >= n {
|
||||
t.Errorf("Expected a num < %d, but got %d", n, rand)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRandInt32(t *testing.T) {
|
||||
var n int32 = 100
|
||||
var rand int32 = GetRand().GetRandInt32(n)
|
||||
if rand >= n {
|
||||
t.Errorf("Expected a num < %d, but got %d", n, rand)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRandInt64(t *testing.T) {
|
||||
var n int64 = 100
|
||||
var rand int64 = GetRand().GetRandInt64(n)
|
||||
if rand >= n {
|
||||
t.Errorf("Expected a num < %d, but got %d", n, rand)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRandFloat32(t *testing.T) {
|
||||
var rand float32 = GetRand().GetRandFloat32()
|
||||
if rand >= 1 {
|
||||
t.Errorf("Expected a num < 1, but got %f", rand)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRandFloat64(t *testing.T) {
|
||||
var rand float64 = GetRand().GetRandFloat64()
|
||||
if rand >= 1 {
|
||||
t.Errorf("Expected a num < 1, but got %f", rand)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRandNumList(t *testing.T) {
|
||||
if _, err := GetRand().GetRandNumList(11, 10, 11, false); err.Error() != "minValue can't be bigger than maxValue." {
|
||||
t.Error("Expected err, but got nil")
|
||||
}
|
||||
|
||||
if _, err := GetRand().GetRandNumList(1, 10, 11, false); err.Error() != "随机的数量超过区间的元素数量" {
|
||||
t.Error("Expected err, but got nil")
|
||||
}
|
||||
|
||||
if _, err := GetRand().GetRandNumList(1, 10001, 10, false); err.Error() != "随机数的区间不能大于10000" {
|
||||
t.Error("Expected err, but got nil")
|
||||
}
|
||||
|
||||
randNumList, _ := GetRand().GetRandNumList(1, 10, 1, false)
|
||||
fmt.Printf("randNumList:%v\n", randNumList)
|
||||
randNumList, _ = GetRand().GetRandNumList(1, 10, 3, false)
|
||||
fmt.Printf("randNumList:%v\n", randNumList)
|
||||
randNumList, _ = GetRand().GetRandNumList(1, 10, 5, false)
|
||||
fmt.Printf("randNumList:%v\n", randNumList)
|
||||
randNumList, _ = GetRand().GetRandNumList(1, 10, 7, false)
|
||||
fmt.Printf("randNumList:%v\n", randNumList)
|
||||
randNumList, _ = GetRand().GetRandNumList(1, 10, 9, false)
|
||||
fmt.Printf("randNumList:%v\n", randNumList)
|
||||
randNumList, _ = GetRand().GetRandNumList(1, 10, 11, true)
|
||||
fmt.Printf("randNumList:%v\n", randNumList)
|
||||
}
|
||||
|
||||
func TestGetRandIntList(t *testing.T) {
|
||||
source := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||
|
||||
if _, err := GetRand().GetRandIntList(source, 11, false); err.Error() != "随机的数量超过列表的元素数量" {
|
||||
t.Error("Expected err, but got nil")
|
||||
}
|
||||
|
||||
randIntList, _ := GetRand().GetRandIntList(source, 1, false)
|
||||
fmt.Printf("randIntList:%v\n", randIntList)
|
||||
randIntList, _ = GetRand().GetRandIntList(source, 3, false)
|
||||
fmt.Printf("randIntList:%v\n", randIntList)
|
||||
randIntList, _ = GetRand().GetRandIntList(source, 5, false)
|
||||
fmt.Printf("randIntList:%v\n", randIntList)
|
||||
randIntList, _ = GetRand().GetRandIntList(source, 7, false)
|
||||
fmt.Printf("randIntList:%v\n", randIntList)
|
||||
randIntList, _ = GetRand().GetRandIntList(source, 9, false)
|
||||
fmt.Printf("randIntList:%v\n", randIntList)
|
||||
randIntList, _ = GetRand().GetRandIntList(source, 10, true)
|
||||
fmt.Printf("randIntList:%v\n", randIntList)
|
||||
}
|
||||
|
||||
func TestGetRandInterfaceList(t *testing.T) {
|
||||
item1 := NewItem(1, "name1", 1)
|
||||
item2 := NewItem(2, "name1", 1)
|
||||
item3 := NewItem(3, "name1", 1)
|
||||
item4 := NewItem(4, "name1", 1)
|
||||
item5 := NewItem(5, "name1", 1)
|
||||
item6 := NewItem(6, "name1", 1)
|
||||
item7 := NewItem(7, "name1", 1)
|
||||
item8 := NewItem(8, "name1", 1)
|
||||
item9 := NewItem(9, "name1", 1)
|
||||
item10 := NewItem(10, "name1", 1)
|
||||
|
||||
source := make([]interface{}, 0, 10)
|
||||
source = append(source, item1)
|
||||
source = append(source, item2)
|
||||
source = append(source, item3)
|
||||
source = append(source, item4)
|
||||
source = append(source, item5)
|
||||
source = append(source, item6)
|
||||
source = append(source, item7)
|
||||
source = append(source, item8)
|
||||
source = append(source, item9)
|
||||
source = append(source, item10)
|
||||
|
||||
if _, err := GetRand().GetRandInterfaceList(source, 11, false); err.Error() != "随机的数量超过列表的元素数量" {
|
||||
t.Error("Expected err, but got nil")
|
||||
}
|
||||
|
||||
randInterfaceList, _ := GetRand().GetRandInterfaceList(source, 1, false)
|
||||
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
|
||||
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 3, false)
|
||||
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
|
||||
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 5, false)
|
||||
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
|
||||
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 7, false)
|
||||
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
|
||||
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 9, false)
|
||||
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
|
||||
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 10, true)
|
||||
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
|
||||
}
|
||||
|
||||
func TestGetRandWeight(t *testing.T) {
|
||||
source := make([]IWeight, 0, 10)
|
||||
if _, err := GetRand().GetRandWeight(source); err == nil {
|
||||
t.Errorf("err should not be nil, but it's nil")
|
||||
}
|
||||
|
||||
item1 := NewItem(1, "name1", 1)
|
||||
item2 := NewItem(2, "name2", 2)
|
||||
item3 := NewItem(3, "name3", 3)
|
||||
item4 := NewItem(4, "name4", 4)
|
||||
item5 := NewItem(5, "name5", 5)
|
||||
item6 := NewItem(6, "name6", 60)
|
||||
item7 := NewItem(7, "name7", 70)
|
||||
item8 := NewItem(8, "name8", 80)
|
||||
item9 := NewItem(9, "name9", 90)
|
||||
item10 := NewItem(10, "name10", 100)
|
||||
|
||||
source = append(source, item1)
|
||||
source = append(source, item2)
|
||||
source = append(source, item3)
|
||||
source = append(source, item4)
|
||||
source = append(source, item5)
|
||||
source = append(source, item6)
|
||||
source = append(source, item7)
|
||||
source = append(source, item8)
|
||||
source = append(source, item9)
|
||||
source = append(source, item10)
|
||||
|
||||
data := make(map[int]int)
|
||||
for i := 0; i < 10000; i++ {
|
||||
if result, err := GetRand().GetRandWeight(source); err != nil {
|
||||
t.Errorf("err should be nil, but it's not:%s", err)
|
||||
} else {
|
||||
if item, ok := result.(*Item); !ok {
|
||||
t.Errorf("convert to Item failed")
|
||||
} else {
|
||||
if count, ok := data[item.Id]; ok {
|
||||
data[item.Id] = count + 1
|
||||
} else {
|
||||
data[item.Id] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total := 0
|
||||
for _, v := range data {
|
||||
total += v
|
||||
}
|
||||
|
||||
k := 1
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
k = 2
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
k = 3
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
k = 4
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
k = 5
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
k = 6
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
k = 7
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
k = 8
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
k = 9
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
k = 10
|
||||
if v, ok := data[k]; ok {
|
||||
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRandWeight2(t *testing.T) {
|
||||
source := make([]IWeight, 0, 10)
|
||||
if _, err := GetRand().GetRandWeight(source); err == nil {
|
||||
t.Errorf("err should not be nil, but it's nil")
|
||||
}
|
||||
|
||||
item1 := NewItem(1, "name1", 1)
|
||||
item2 := NewItem(2, "name2", 2)
|
||||
item3 := NewItem(3, "name3", 3)
|
||||
item4 := NewItem(4, "name4", 4)
|
||||
item5 := NewItem(5, "name5", 5)
|
||||
item6 := NewItem(6, "name6", 60)
|
||||
item7 := NewItem(7, "name7", 70)
|
||||
item8 := NewItem(8, "name8", 80)
|
||||
item9 := NewItem(9, "name9", 90)
|
||||
item10 := NewItem(10, "name10", 100)
|
||||
|
||||
source = append(source, item1)
|
||||
source = append(source, item2)
|
||||
source = append(source, item3)
|
||||
source = append(source, item4)
|
||||
source = append(source, item5)
|
||||
source = append(source, item6)
|
||||
source = append(source, item7)
|
||||
source = append(source, item8)
|
||||
source = append(source, item9)
|
||||
source = append(source, item10)
|
||||
|
||||
rindexs, err := GetRand().GetRandItemsByWeight(source, 2, false)
|
||||
if err != nil {
|
||||
t.Errorf("GetRandItemsByWeight出错:%s", err)
|
||||
}
|
||||
if len(rindexs) != 2 || rindexs[0] == rindexs[1] {
|
||||
t.Errorf("GetRandItemsByWeight随机内容出错")
|
||||
}
|
||||
|
||||
rindexs, err = GetRand().GetRandItemsByWeight(source, 10, false)
|
||||
if err != nil {
|
||||
t.Errorf("GetRandItemsByWeight出错:%s", err)
|
||||
}
|
||||
|
||||
if len(rindexs) != 10 {
|
||||
t.Errorf("GetRandItemsByWeight随机内容出错")
|
||||
}
|
||||
|
||||
_, err = GetRand().GetRandItemsByWeight(source, 12, false)
|
||||
if err == nil {
|
||||
t.Errorf("GetRandItemsByWeight出错:%s", err)
|
||||
}
|
||||
|
||||
rindexs, err = GetRand().GetRandItemsByWeight(source, 15, true)
|
||||
if err != nil {
|
||||
t.Errorf("GetRandItemsByWeight出错:%s", err)
|
||||
}
|
||||
if len(rindexs) != 15 {
|
||||
t.Errorf("GetRandItemsByWeight随机内容出错")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
Id int
|
||||
Name string
|
||||
Weight int
|
||||
}
|
||||
|
||||
func (item *Item) GetWeight() int {
|
||||
return item.Weight
|
||||
}
|
||||
|
||||
func (item *Item) String() string {
|
||||
return fmt.Sprintf("Id:%d,Name:%s\n", item.Id, item.Name)
|
||||
}
|
||||
|
||||
func NewItem(id int, name string, weight int) *Item {
|
||||
return &Item{
|
||||
Id: id,
|
||||
Name: name,
|
||||
Weight: weight,
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GetRandom(t *testing.T) {
|
||||
rand, err := GetRand().GetRandNumList(1, 10000, 10, true)
|
||||
if err != nil {
|
||||
t.Log(fmt.Errorf("获取随机数错误:%s", err))
|
||||
}
|
||||
|
||||
t.Log(rand)
|
||||
}
|
||||
381
trunk/goutil/mathUtil/safeRand.go
Normal file
381
trunk/goutil/mathUtil/safeRand.go
Normal file
@@ -0,0 +1,381 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
//SafeRand 安全的随机
|
||||
type SafeRand struct {
|
||||
*rand.Rand
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func GetSafeRand() *SafeRand {
|
||||
return &SafeRand{
|
||||
Rand: rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
}
|
||||
}
|
||||
|
||||
func GetSafeRandInSeed(seed int64) *SafeRand {
|
||||
return &SafeRand{
|
||||
Rand: rand.New(rand.NewSource(seed)),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *SafeRand) Int() int {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
return this.Rand.Int()
|
||||
}
|
||||
|
||||
func (this *SafeRand) Intn(n int) int {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
return this.Rand.Intn(n)
|
||||
}
|
||||
|
||||
func (this *SafeRand) Int31() int32 {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
return this.Rand.Int31()
|
||||
}
|
||||
|
||||
func (this *SafeRand) Int31n(n int32) int32 {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
return this.Rand.Int31n(n)
|
||||
}
|
||||
|
||||
func (this *SafeRand) Int63() int64 {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
return this.Rand.Int63()
|
||||
}
|
||||
|
||||
func (this *SafeRand) Int63n(n int64) int64 {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
return this.Rand.Int63n(n)
|
||||
}
|
||||
|
||||
func (this *SafeRand) Float64() float64 {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
return this.Rand.Float64()
|
||||
}
|
||||
|
||||
func (this *SafeRand) Float32() float32 {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
return this.Rand.Float32()
|
||||
}
|
||||
|
||||
// 获取指定区间的随机数[lower, upper)
|
||||
// lower:区间下限
|
||||
// upper:区间上限
|
||||
// 返回值:随机数
|
||||
func (this *SafeRand) GetRandRangeInt(lower, upper int) int {
|
||||
return lower + this.Intn(upper-lower)
|
||||
}
|
||||
|
||||
// 获取指定区间的随机数[lower, upper)
|
||||
// lower:区间下限
|
||||
// upper:区间上限
|
||||
// 返回值:随机数
|
||||
func (this *SafeRand) GetRandRangeInt32(lower, upper int32) int32 {
|
||||
return lower + this.Int31n(upper-lower)
|
||||
}
|
||||
|
||||
// 获取指定区间的随机数[lower, upper)
|
||||
// lower:区间下限
|
||||
// upper:区间上限
|
||||
// 返回值:随机数
|
||||
func (this *SafeRand) GetRandRangeInt64(lower, upper int64) int64 {
|
||||
return lower + this.Int63n(upper-lower)
|
||||
}
|
||||
|
||||
// 获取随机数[0, n)
|
||||
// randObj:随机对象
|
||||
// n:范围上限
|
||||
// 返回值:随机数
|
||||
func (this *SafeRand) GetRandInt(n int) int {
|
||||
return this.Intn(n)
|
||||
}
|
||||
|
||||
// 获取随机数[0, n)
|
||||
// n:范围上限
|
||||
// 返回值:随机数
|
||||
func (this *SafeRand) GetRandInt32(n int32) int32 {
|
||||
return this.Int31n(n)
|
||||
}
|
||||
|
||||
// 获取随机数[0, n)
|
||||
// randObj:随机对象
|
||||
// n:范围上限
|
||||
// 返回值:随机数
|
||||
func (this *SafeRand) GetRandInt64(n int64) int64 {
|
||||
return this.Int63n(n)
|
||||
}
|
||||
|
||||
// 获取随机数[0, 1)
|
||||
// randObj:随机对象
|
||||
// 返回值:随机数
|
||||
func (this *SafeRand) GetRandFloat32() float32 {
|
||||
return this.Float32()
|
||||
}
|
||||
|
||||
// 获取随机数[0, 1)
|
||||
// 返回值:随机数
|
||||
func (this *SafeRand) GetRandFloat64() float64 {
|
||||
return this.Float64()
|
||||
}
|
||||
|
||||
// 获取随机数列表(1~10000,超过10000会抛出异常)
|
||||
// minValue:获取随机数的区间下限值
|
||||
// maxValue:获取随机数的区间上限值
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *SafeRand) GetRandNumList(minValue, maxValue, count int, ifAllowDuplicate bool) ([]int, error) {
|
||||
if minValue > maxValue {
|
||||
return nil, errors.New("minValue can't be bigger than maxValue.")
|
||||
}
|
||||
|
||||
if !ifAllowDuplicate && (maxValue-minValue+1) < count {
|
||||
return nil, errors.New("随机的数量超过区间的元素数量")
|
||||
}
|
||||
|
||||
if (maxValue - minValue + 1) > 10000 {
|
||||
return nil, errors.New("随机数的区间不能大于10000")
|
||||
}
|
||||
|
||||
// 定义原始数据
|
||||
sourceCount := maxValue - minValue + 1
|
||||
source := make([]int, sourceCount, sourceCount)
|
||||
for index := 0; index < sourceCount; index++ {
|
||||
source[index] = minValue + index
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]int, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的int列表
|
||||
// source:源列表
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *SafeRand) GetRandIntList(source []int, count int, ifAllowDuplicate bool) ([]int, error) {
|
||||
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
|
||||
if ifAllowDuplicate == false && len(source) < count {
|
||||
return nil, errors.New("随机的数量超过列表的元素数量")
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]int, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的int32列表
|
||||
// source:源列表
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *SafeRand) GetRandInt32List(source []int32, count int, ifAllowDuplicate bool) ([]int32, error) {
|
||||
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
|
||||
if ifAllowDuplicate == false && len(source) < count {
|
||||
return nil, errors.New("随机的数量超过列表的元素数量")
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]int32, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的int64列表
|
||||
// source:源列表
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *SafeRand) GetRandInt64List(source []int64, count int, ifAllowDuplicate bool) ([]int64, error) {
|
||||
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
|
||||
if ifAllowDuplicate == false && len(source) < count {
|
||||
return nil, errors.New("随机的数量超过列表的元素数量")
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]int64, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的interface{}列表
|
||||
// source:源列表
|
||||
// count:随机数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机数列表
|
||||
func (this *SafeRand) GetRandInterfaceList(source []interface{}, count int, ifAllowDuplicate bool) ([]interface{}, error) {
|
||||
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
|
||||
if ifAllowDuplicate == false && len(source) < count {
|
||||
return nil, errors.New("随机的数量超过列表的元素数量")
|
||||
}
|
||||
|
||||
// 定义返回值
|
||||
resultList := make([]interface{}, 0, count)
|
||||
|
||||
// 获取随机的索引列表
|
||||
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
|
||||
for _, index := range randIndextList {
|
||||
// 判断是否已经取到足够数量的数据?
|
||||
if count <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
resultList = append(resultList, source[index])
|
||||
count -= 1
|
||||
}
|
||||
|
||||
return resultList, nil
|
||||
}
|
||||
|
||||
// 获取随机的索引列表
|
||||
// count:数量
|
||||
// ifAllowDuplicate:是否允许重复
|
||||
// 返回值
|
||||
// 随机索引值列表
|
||||
func (this *SafeRand) getRandIndexList(maxNum, count int, ifAllowDuplicate bool) []int {
|
||||
// 定义返回值
|
||||
randIndextList := make([]int, 0, count)
|
||||
|
||||
// 使用源列表的数据量来初始化一个仅存放索引值的数组
|
||||
indexList := make([]int, maxNum, maxNum)
|
||||
for index := 0; index < maxNum; index++ {
|
||||
indexList[index] = index
|
||||
}
|
||||
|
||||
// 遍历列表并获取随机对象(通过不断缩小随机的范围来实现)
|
||||
maxIndex := len(indexList) - 1
|
||||
for {
|
||||
if len(randIndextList) < count {
|
||||
// 获取随机索引(由于Next方法不取上限值,所以需要maxIndex+1)
|
||||
randIndex := this.Intn(maxIndex + 1)
|
||||
|
||||
// 将数据添加到列表,并增加findCount
|
||||
randIndextList = append(randIndextList, indexList[randIndex])
|
||||
|
||||
// 如果不允许重复,则需要特殊处理
|
||||
if !ifAllowDuplicate {
|
||||
// 将该位置的数据和最大位置的数据进行交换
|
||||
indexList[randIndex], indexList[maxIndex] = indexList[maxIndex], indexList[randIndex]
|
||||
|
||||
// 将随机的范围缩小
|
||||
maxIndex -= 1
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return randIndextList
|
||||
}
|
||||
|
||||
// 获取带权重的随机数据
|
||||
// source:源数据
|
||||
// 返回值
|
||||
// 数据项
|
||||
// 错误对象
|
||||
func (this *SafeRand) GetRandWeight(source []IWeight) (result IWeight, err error) {
|
||||
if source == nil || len(source) == 0 {
|
||||
err = errors.New("待随机的列表为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 计算出总的数据量,并随机一个[0, total)的值
|
||||
total := 0
|
||||
for _, item := range source {
|
||||
total += item.GetWeight()
|
||||
}
|
||||
|
||||
randNum := this.GetRandInt(total)
|
||||
|
||||
// 根据随机出来的值,判断位于哪个区间
|
||||
total = 0
|
||||
for _, item := range source {
|
||||
total += item.GetWeight()
|
||||
if randNum < total {
|
||||
result = item
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = errors.New("未找到有效的数据")
|
||||
return
|
||||
}
|
||||
47
trunk/goutil/mathUtil/saferand_test.go
Normal file
47
trunk/goutil/mathUtil/saferand_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetSafeRandProccess(t *testing.T) {
|
||||
// r := GetSafeRand()
|
||||
// for {
|
||||
// go r.Int()
|
||||
// go r.Intn(10)
|
||||
// go r.Int31()
|
||||
// go r.Int31n(10)
|
||||
// go r.Int63()
|
||||
// go r.Int63n(10)
|
||||
// go r.Float64()
|
||||
// go r.Float32()
|
||||
// }
|
||||
|
||||
// r1 := GetRand()
|
||||
// for {
|
||||
// go r1.Int()
|
||||
// }
|
||||
}
|
||||
|
||||
func BenchmarkInt(b *testing.B) {
|
||||
r := GetSafeRand()
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
r.Int()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkGetRandNumList(b *testing.B) {
|
||||
r := GetSafeRand()
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, err := r.GetRandNumList(1, 10000, 10, true)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
37
trunk/goutil/mathUtil/size.go
Normal file
37
trunk/goutil/mathUtil/size.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 获取字节大小的描述信息
|
||||
// size:字节大小
|
||||
// 返回值:
|
||||
// 描述信息
|
||||
func GetSizeDesc(size int64) string {
|
||||
str := ""
|
||||
|
||||
// 判断输入是否超过int64的范围
|
||||
if size < 0 || size > (1<<63-1) {
|
||||
return str
|
||||
}
|
||||
|
||||
switch {
|
||||
case size >= 1024*1024*1024*1024*1024*1024:
|
||||
str = fmt.Sprintf("%.2fEB", float64(size)/1024/1024/1024/1024/1024/1024)
|
||||
case size >= 1024*1024*1024*1024*1024:
|
||||
str = fmt.Sprintf("%.2fPB", float64(size)/1024/1024/1024/1024/1024)
|
||||
case size >= 1024*1024*1024*1024:
|
||||
str = fmt.Sprintf("%.2fTB", float64(size)/1024/1024/1024/1024)
|
||||
case size >= 1024*1024*1024:
|
||||
str = fmt.Sprintf("%.2fGB", float64(size)/1024/1024/1024)
|
||||
case size >= 1024*1024:
|
||||
str = fmt.Sprintf("%dMB", size/1024/1024)
|
||||
case size >= 1024:
|
||||
str = fmt.Sprintf("%dKB", size/1024)
|
||||
default:
|
||||
str = fmt.Sprintf("%dB", size)
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
61
trunk/goutil/mathUtil/size_test.go
Normal file
61
trunk/goutil/mathUtil/size_test.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package mathUtil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetSizeDesc(t *testing.T) {
|
||||
var size int64
|
||||
var expectedStr string
|
||||
var finalStr string
|
||||
|
||||
size = 1
|
||||
expectedStr = "1B"
|
||||
finalStr = GetSizeDesc(size)
|
||||
if finalStr != expectedStr {
|
||||
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
|
||||
}
|
||||
|
||||
size *= 1024
|
||||
expectedStr = "1KB"
|
||||
finalStr = GetSizeDesc(size)
|
||||
if finalStr != expectedStr {
|
||||
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
|
||||
}
|
||||
|
||||
size *= 1024
|
||||
expectedStr = "1MB"
|
||||
finalStr = GetSizeDesc(size)
|
||||
if finalStr != expectedStr {
|
||||
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
|
||||
}
|
||||
|
||||
size *= 1024
|
||||
expectedStr = "1.00GB"
|
||||
finalStr = GetSizeDesc(size)
|
||||
if finalStr != expectedStr {
|
||||
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
|
||||
}
|
||||
|
||||
size *= 1024
|
||||
expectedStr = "1.00TB"
|
||||
finalStr = GetSizeDesc(size)
|
||||
if finalStr != expectedStr {
|
||||
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
|
||||
}
|
||||
|
||||
size *= 1024
|
||||
expectedStr = "1.00PB"
|
||||
finalStr = GetSizeDesc(size)
|
||||
if finalStr != expectedStr {
|
||||
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
|
||||
}
|
||||
|
||||
size *= 1024
|
||||
expectedStr = "1.00EB"
|
||||
finalStr = GetSizeDesc(size)
|
||||
if finalStr != expectedStr {
|
||||
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user