go-hep.org/x/hep@v0.40.0/groot/root/datatypes.go (about)

     1  // Copyright ©2018 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package root // import "go-hep.org/x/hep/groot/root"
     6  
     7  import (
     8  	"encoding/binary"
     9  	"math"
    10  )
    11  
    12  // Float16 is a float32 in memory, written with a truncated mantissa.
    13  type Float16 float32
    14  
    15  func (Float16) DescrNPy() string { return "'f2'" }
    16  
    17  func (f Float16) MarshalNPy(bo binary.ByteOrder) ([]byte, error) {
    18  	var buf [2]byte
    19  	bo.PutUint16(buf[:], float16bits(float32(f)))
    20  	return buf[:], nil
    21  }
    22  
    23  func (f *Float16) UnmarshalNPy(bo binary.ByteOrder, buf []byte) error {
    24  	*f = Float16(float16frombits(bo.Uint16(buf)))
    25  	return nil
    26  }
    27  
    28  func float16bits(f float32) uint16 {
    29  	var (
    30  		bits = math.Float32bits(f)
    31  		sign = uint16((bits >> 31) & 0x1)
    32  		exp  = (bits >> 23) & 0xff
    33  		res  = int16(exp) - 127 + 15
    34  		fc   = uint16(bits>>13) & 0x3ff
    35  	)
    36  	switch {
    37  	case exp == 0:
    38  		res = 0
    39  	case exp == 0xff:
    40  		res = 0x1f
    41  	case res > 0x1e:
    42  		res = 0x1f
    43  		fc = 0
    44  	case res < 0x01:
    45  		res = 0
    46  		fc = 0
    47  	}
    48  	return (sign << 15) | uint16(res<<10) | fc
    49  }
    50  
    51  func float16frombits(bits uint16) float32 {
    52  	var (
    53  		sign = uint32((bits >> 15) & 0x1)
    54  		exp  = (bits >> 10) & 0x1f
    55  		res  = uint32(exp) + 127 - 15
    56  		fc   = uint32(bits & 0x3ff)
    57  	)
    58  	switch {
    59  	case exp == 0:
    60  		res = 0
    61  	case exp == 0x1f:
    62  		res = 0xff
    63  	}
    64  	return math.Float32frombits((sign << 31) | (res << 23) | (fc << 13))
    65  
    66  }
    67  
    68  // Double32 is a float64 in memory, written as a float32 to disk.
    69  type Double32 float64
    70  
    71  func (Double32) DescrNPy() string { return "'f4'" }
    72  
    73  func (f Double32) MarshalNPy(bo binary.ByteOrder) ([]byte, error) {
    74  	var buf [4]byte
    75  	bo.PutUint32(buf[:], math.Float32bits(float32(f)))
    76  	return buf[:], nil
    77  }
    78  
    79  func (f *Double32) UnmarshalNPy(bo binary.ByteOrder, buf []byte) error {
    80  	*f = Double32(math.Float32frombits(bo.Uint32(buf)))
    81  	return nil
    82  }