gitee.com/quant1x/gox@v1.7.6/encoding/binary/struc/custom_float16.go (about) 1 package struc 2 3 import ( 4 "encoding/binary" 5 "io" 6 "math" 7 "strconv" 8 ) 9 10 type Float16 float64 11 12 func (f *Float16) Pack(p []byte, opt *Options) (int, error) { 13 order := opt.Order 14 if order == nil { 15 order = binary.BigEndian 16 } 17 sign := uint16(0) 18 if *f < 0 { 19 sign = 1 20 } 21 var frac, exp uint16 22 if math.IsInf(float64(*f), 0) { 23 exp = 0x1f 24 frac = 0 25 } else if math.IsNaN(float64(*f)) { 26 exp = 0x1f 27 frac = 1 28 } else { 29 bits := math.Float64bits(float64(*f)) 30 exp64 := (bits >> 52) & 0x7ff 31 if exp64 != 0 { 32 exp = uint16((exp64 - 1023 + 15) & 0x1f) 33 } 34 frac = uint16((bits >> 42) & 0x3ff) 35 } 36 var out uint16 37 out |= sign << 15 38 out |= exp << 10 39 out |= frac & 0x3ff 40 order.PutUint16(p, out) 41 return 2, nil 42 } 43 func (f *Float16) Unpack(r io.Reader, length int, opt *Options) error { 44 order := opt.Order 45 if order == nil { 46 order = binary.BigEndian 47 } 48 var tmp [2]byte 49 if _, err := r.Read(tmp[:]); err != nil { 50 return err 51 } 52 val := order.Uint16(tmp[:2]) 53 sign := (val >> 15) & 1 54 exp := int16((val >> 10) & 0x1f) 55 frac := val & 0x3ff 56 if exp == 0x1f { 57 if frac != 0 { 58 *f = Float16(math.NaN()) 59 } else { 60 *f = Float16(math.Inf(int(sign)*-2 + 1)) 61 } 62 } else { 63 var bits uint64 64 bits |= uint64(sign) << 63 65 bits |= uint64(frac) << 42 66 if exp > 0 { 67 bits |= uint64(exp-15+1023) << 52 68 } 69 *f = Float16(math.Float64frombits(bits)) 70 } 71 return nil 72 } 73 func (f *Float16) Size(opt *Options) int { 74 return 2 75 } 76 func (f *Float16) String() string { 77 return strconv.FormatFloat(float64(*f), 'g', -1, 32) 78 }