go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/fixed.go (about)

     1  package fu
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  )
     7  
     8  // value in range [-1..1] with 2 digits precession
     9  type Fixed8 struct{ int8 }
    10  
    11  func (v Fixed8) Raw() int8 {
    12  	return v.int8
    13  }
    14  
    15  func (v Fixed8) String() string {
    16  	return fmt.Sprint(v.Float32())
    17  }
    18  
    19  func (v Fixed8) Float32() float32 {
    20  	return float32(v.int8) / 100
    21  }
    22  
    23  func AsFixed8(v float32) Fixed8 {
    24  	return Fixed8{int8(v * 100)}
    25  }
    26  
    27  func RawAsFixed8(v int8) Fixed8 {
    28  	return Fixed8{v}
    29  }
    30  
    31  func Fast8f(s string) (v8 Fixed8, err error) {
    32  	v, err := Fast32f(s)
    33  	if err != nil {
    34  		return
    35  	}
    36  	if v > 1.27 || v < -1.27 {
    37  		return Fixed8{}, fmt.Errorf("fixed8 value out of range [-1.27...1.27] : %v", v)
    38  	}
    39  	v8 = AsFixed8(v)
    40  	return
    41  }
    42  
    43  var fast32iTable = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    44  
    45  func Fast32f(s string) (float32, error) {
    46  	sign := float32(1)
    47  	q := 0
    48  	exp := 0
    49  	if s[0] == '-' {
    50  		sign = float32(-1)
    51  		s = s[1:]
    52  	}
    53  	for _, c := range s {
    54  		if c == '.' {
    55  			exp = 1
    56  		} else if c >= '0' && c <= '9' {
    57  			q = q*10 + fast32iTable[c-'0']
    58  			exp *= 10
    59  		} else {
    60  			return Slow32f(s)
    61  		}
    62  	}
    63  	f := float32(q)
    64  	if exp > 0 {
    65  		f /= float32(exp)
    66  	}
    67  	return f * sign, nil
    68  }
    69  
    70  func Slow32f(s string) (float32, error) {
    71  	v, err := strconv.ParseFloat(s, 32)
    72  	return float32(v), err
    73  }