gitee.com/quant1x/num@v0.3.2/type_float32.go (about)

     1  package num
     2  
     3  import (
     4  	"fmt"
     5  	"gitee.com/quant1x/gox/exception"
     6  	"gitee.com/quant1x/gox/logger"
     7  	"gitee.com/quant1x/num/x32"
     8  	"math"
     9  	"reflect"
    10  	"strconv"
    11  )
    12  
    13  const (
    14  	errorFloat32Base = errorTypeBase + int(reflect.Float32)*100
    15  )
    16  
    17  const (
    18  	MaxFloat32                  = float32(math.MaxFloat32)             // float32最大值
    19  	MinFloat32                  = float32(math.SmallestNonzeroFloat32) // float32最小值
    20  	StringTrue2Float32  float32 = float32(1)                           // 字符串true转float32
    21  	StringFalse2Float32 float32 = float32(0)                           // 字符串false转float32
    22  )
    23  
    24  var (
    25  	__nilToFloat32 = float32(math.NaN())
    26  )
    27  
    28  func Float32NaN() float32 {
    29  	return float32(NaN())
    30  }
    31  
    32  // Float32IsNaN 判断float32是否NaN
    33  func Float32IsNaN(f float32) bool {
    34  	return Float64IsNaN(float64(f))
    35  }
    36  
    37  // 普通的处理方式, 将切片强制转换成float32
    38  func sliceNumberToFloat32[T Number](s []T) []float32 {
    39  	count := len(s)
    40  	if count == 0 {
    41  		return []float32{}
    42  	}
    43  	d := make([]float32, count)
    44  	for idx, iv := range s {
    45  		// 强制转换
    46  		d[idx] = float32(iv)
    47  	}
    48  	return d
    49  }
    50  
    51  // SliceToFloat32 any输入只能是一维slice或者数组
    52  func SliceToFloat32(v any) []float32 {
    53  	var vs []float32
    54  	switch values := v.(type) {
    55  	case []int8:
    56  		return sliceNumberToFloat32(values)
    57  	case []uint8:
    58  		return sliceNumberToFloat32(values)
    59  	case []int16:
    60  		return sliceNumberToFloat32(values)
    61  	case []uint16:
    62  		return sliceNumberToFloat32(values)
    63  	case []int32: // 加速
    64  		return x32.FromInt32(values)
    65  	case []uint32:
    66  		return sliceNumberToFloat32(values)
    67  	case []int64: // 加速
    68  		return x32.FromInt64(values)
    69  	case []uint64:
    70  		return sliceNumberToFloat32(values)
    71  	case []int:
    72  		return sliceNumberToFloat32(values)
    73  	case []uint:
    74  		return sliceNumberToFloat32(values)
    75  	case []float32: // 克隆
    76  		//return slices.Clone(values)
    77  		return values
    78  	case []float64: // 加速
    79  		return x32.FromFloat64(values)
    80  	case []bool:
    81  		count := len(values)
    82  		if count == 0 {
    83  			return []float32{}
    84  		}
    85  		// 加速
    86  		return x32.FromBool(values)
    87  	case []string:
    88  		count := len(values)
    89  		if count == 0 {
    90  			return []float32{}
    91  		}
    92  		vs = make([]float32, count)
    93  		for idx, iv := range values {
    94  			vs[idx] = float32(AnyToFloat64(iv))
    95  		}
    96  	default:
    97  		vv := reflect.ValueOf(v)
    98  		vk := vv.Kind()
    99  		panic(exception.New(errorFloat32Base+0, fmt.Sprintf("Unsupported type: %s", vk.String())))
   100  	}
   101  	return []float32{}
   102  }
   103  
   104  // ParseFloat32 字符串转float32
   105  func ParseFloat32(s string, v any) float32 {
   106  	defer func() {
   107  		// 解析失败以后输出日志, 以备检查
   108  		if err := recover(); err != nil {
   109  			logger.Errorf("ParseFloat32 %+v, error=%+v\n", v, err)
   110  		}
   111  	}()
   112  
   113  	if IsEmpty(s) {
   114  		// TODO:NaN是针对64位, 这样直接转换应该有问题, 需要进一步确认
   115  		return __nilToFloat32
   116  	}
   117  	if StringIsTrue(s) {
   118  		return StringTrue2Float32
   119  	} else if StringIsFalse(s) {
   120  		return StringFalse2Float32
   121  	}
   122  
   123  	f, err := strconv.ParseFloat(s, 32)
   124  	if err == nil {
   125  		return float32(f)
   126  	}
   127  	if IgnoreParseExceptions {
   128  		return __nilToFloat32
   129  	}
   130  	_ = v.(float32) // Intentionally panic
   131  	return __nilToFloat32
   132  }
   133  
   134  func AnyToFloat32(v any) float32 {
   135  	if vv, ok := ExtractValueFromPointer(v); ok {
   136  		v = vv
   137  	}
   138  
   139  	f := valueToNumber(v, __nilToFloat32, BoolToFloat32, ParseFloat32)
   140  	return f
   141  }