mirror of
https://github.com/gogf/gf.git
synced 2025-04-05 03:05:05 +08:00
162 lines
4.1 KiB
Go
162 lines
4.1 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
package converter
|
|
|
|
import (
|
|
"reflect"
|
|
"strconv"
|
|
|
|
"github.com/gogf/gf/v2/encoding/gbinary"
|
|
"github.com/gogf/gf/v2/errors/gcode"
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
"github.com/gogf/gf/v2/internal/empty"
|
|
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
|
)
|
|
|
|
// Float32 converts `any` to float32.
|
|
func (c *Converter) Float32(any any) (float32, error) {
|
|
if empty.IsNil(any) {
|
|
return 0, nil
|
|
}
|
|
switch value := any.(type) {
|
|
case float32:
|
|
return value, nil
|
|
case float64:
|
|
return float32(value), nil
|
|
case []byte:
|
|
// TODO: It might panic here for these types.
|
|
return gbinary.DecodeToFloat32(value), nil
|
|
default:
|
|
rv := reflect.ValueOf(any)
|
|
switch rv.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return float32(rv.Int()), nil
|
|
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
return float32(rv.Uint()), nil
|
|
case reflect.Float32, reflect.Float64:
|
|
return float32(rv.Float()), nil
|
|
case reflect.Bool:
|
|
if rv.Bool() {
|
|
return 1, nil
|
|
}
|
|
return 0, nil
|
|
case reflect.String:
|
|
s := rv.String()
|
|
if s == "" {
|
|
return 0, nil
|
|
}
|
|
f, err := strconv.ParseFloat(s, 32)
|
|
if err != nil {
|
|
return 0, gerror.WrapCodef(
|
|
gcode.CodeInvalidParameter, err, "converting string to float32 failed for: %v", any,
|
|
)
|
|
}
|
|
return float32(f), nil
|
|
case reflect.Ptr:
|
|
if rv.IsNil() {
|
|
return 0, nil
|
|
}
|
|
if f, ok := value.(localinterface.IFloat32); ok {
|
|
return f.Float32(), nil
|
|
}
|
|
return c.Float32(rv.Elem().Interface())
|
|
default:
|
|
if f, ok := value.(localinterface.IFloat32); ok {
|
|
return f.Float32(), nil
|
|
}
|
|
s, err := c.String(any)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if s == "" {
|
|
return 0, nil
|
|
}
|
|
v, err := strconv.ParseFloat(s, 32)
|
|
if err != nil {
|
|
return 0, gerror.WrapCodef(
|
|
gcode.CodeInvalidParameter, err, "converting string to float32 failed for: %v", any,
|
|
)
|
|
}
|
|
return float32(v), nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// Float64 converts `any` to float64.
|
|
func (c *Converter) Float64(any any) (float64, error) {
|
|
if empty.IsNil(any) {
|
|
return 0, nil
|
|
}
|
|
switch value := any.(type) {
|
|
case float32:
|
|
return float64(value), nil
|
|
case float64:
|
|
return value, nil
|
|
case []byte:
|
|
// TODO: It might panic here for these types.
|
|
return gbinary.DecodeToFloat64(value), nil
|
|
default:
|
|
rv := reflect.ValueOf(any)
|
|
switch rv.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return float64(rv.Int()), nil
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
return float64(rv.Uint()), nil
|
|
case reflect.Uintptr:
|
|
return float64(rv.Uint()), nil
|
|
case reflect.Float32, reflect.Float64:
|
|
// Please Note:
|
|
// When the type is float32 or a custom type defined based on float32,
|
|
// switching to float64 may result in a few extra decimal places.
|
|
return rv.Float(), nil
|
|
case reflect.Bool:
|
|
if rv.Bool() {
|
|
return 1, nil
|
|
}
|
|
return 0, nil
|
|
case reflect.String:
|
|
s := rv.String()
|
|
if s == "" {
|
|
return 0, nil
|
|
}
|
|
f, err := strconv.ParseFloat(s, 64)
|
|
if err != nil {
|
|
return 0, gerror.WrapCodef(
|
|
gcode.CodeInvalidParameter, err, "converting string to float64 failed for: %v", any,
|
|
)
|
|
}
|
|
return f, nil
|
|
case reflect.Ptr:
|
|
if rv.IsNil() {
|
|
return 0, nil
|
|
}
|
|
if f, ok := value.(localinterface.IFloat64); ok {
|
|
return f.Float64(), nil
|
|
}
|
|
return c.Float64(rv.Elem().Interface())
|
|
default:
|
|
if f, ok := value.(localinterface.IFloat64); ok {
|
|
return f.Float64(), nil
|
|
}
|
|
s, err := c.String(any)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if s == "" {
|
|
return 0, nil
|
|
}
|
|
v, err := strconv.ParseFloat(s, 64)
|
|
if err != nil {
|
|
return 0, gerror.WrapCodef(
|
|
gcode.CodeInvalidParameter, err, "converting string to float64 failed for: %v", any,
|
|
)
|
|
}
|
|
return v, nil
|
|
}
|
|
}
|
|
}
|