Browse Source

reflect: Convert(): add Float() conversions

pull/3609/head
Damian Gryski 2 years ago
committed by Ayke
parent
commit
855e12df51
  1. 68
      src/reflect/value.go

68
src/reflect/value.go

@ -330,6 +330,27 @@ func (v Value) Uint() uint64 {
}
}
func (v Value) Float32() float32 {
switch v.Kind() {
case Float32:
if v.isIndirect() || unsafe.Sizeof(float32(0)) > unsafe.Sizeof(uintptr(0)) {
// The float is stored as an external value on systems with 16-bit
// pointers.
return *(*float32)(v.value)
} else {
// The float is directly stored in the interface value on systems
// with 32-bit and 64-bit pointers.
return *(*float32)(unsafe.Pointer(&v.value))
}
case Float64:
return float32(v.Float())
}
panic(&ValueError{Method: "Float", Kind: v.Kind()})
}
func (v Value) Float() float64 {
switch v.Kind() {
case Float32:
@ -1103,6 +1124,24 @@ func convertOp(src Value, typ Type) (Value, bool) {
return cvtUintString(src, rtype), true
}
case Float32, Float64:
switch rtype := typ.(*rawType); rtype.Kind() {
case Int, Int8, Int16, Int32, Int64:
return cvtFloatInt(src, rtype), true
case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
return cvtFloatUint(src, rtype), true
case Float32, Float64:
return cvtFloat(src, rtype), true
}
/*
case Complex64, Complex128:
switch src.Kind() {
case Complex64, Complex128:
return cvtComplex
}
*/
case Slice:
if typ.Kind() == String && !src.typecode.elem().isNamed() {
rtype := typ.(*rawType)
@ -1149,6 +1188,24 @@ func cvtUintFloat(v Value, t *rawType) Value {
return makeFloat(v.flags, float64(v.Uint()), t)
}
func cvtFloatInt(v Value, t *rawType) Value {
return makeInt(v.flags, uint64(int64(v.Float())), t)
}
func cvtFloatUint(v Value, t *rawType) Value {
return makeInt(v.flags, uint64(v.Float()), t)
}
func cvtFloat(v Value, t *rawType) Value {
if v.Type().Kind() == Float32 && t.Kind() == Float32 {
// Don't do any conversion if both types have underlying type float32.
// This avoids converting to float64 and back, which will
// convert a signaling NaN to a quiet NaN. See issue 36400.
return makeFloat32(v.flags, v.Float32(), t)
}
return makeFloat(v.flags, v.Float(), t)
}
//go:linkname stringToBytes runtime.stringToBytesTyped
func stringToBytes(x string) []byte
@ -1209,6 +1266,17 @@ func makeFloat(flags valueFlags, v float64, t *rawType) Value {
}
}
func makeFloat32(flags valueFlags, v float32, t *rawType) Value {
size := t.Size()
ptr := alloc(size, nil)
*(*float32)(ptr) = float32(v)
return Value{
typecode: t,
value: ptr,
flags: flags | valueFlagIndirect,
}
}
func cvtIntString(src Value, t *rawType) Value {
panic("cvtUintString: unimplemented")
}

Loading…
Cancel
Save