github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/encoding/fixedn/fixed8.go (about)

     1  package fixedn
     2  
     3  import (
     4  	"strconv"
     5  	"strings"
     6  
     7  	"github.com/nspcc-dev/neo-go/pkg/io"
     8  )
     9  
    10  const (
    11  	precision = 8
    12  	decimals  = 100000000
    13  )
    14  
    15  // Fixed8 represents a fixed-point number with precision 10^-8.
    16  type Fixed8 int64
    17  
    18  // String implements the Stringer interface.
    19  func (f Fixed8) String() string {
    20  	buf := new(strings.Builder)
    21  	val := int64(f)
    22  	if val < 0 {
    23  		buf.WriteRune('-')
    24  		val = -val
    25  	}
    26  	str := strconv.FormatInt(val/decimals, 10)
    27  	buf.WriteString(str)
    28  	val %= decimals
    29  	if val > 0 {
    30  		buf.WriteRune('.')
    31  		str = strconv.FormatInt(val, 10)
    32  		for i := len(str); i < 8; i++ {
    33  			buf.WriteRune('0')
    34  		}
    35  		buf.WriteString(strings.TrimRight(str, "0"))
    36  	}
    37  	return buf.String()
    38  }
    39  
    40  // FloatValue returns the original value representing Fixed8 as float64.
    41  func (f Fixed8) FloatValue() float64 {
    42  	return float64(f) / decimals
    43  }
    44  
    45  // IntegralValue returns an integer part of the original value representing
    46  // Fixed8 as int64.
    47  func (f Fixed8) IntegralValue() int64 {
    48  	return int64(f) / decimals
    49  }
    50  
    51  // FractionalValue returns a decimal part of the original value. It has the same
    52  // sign as f, so that f = f.IntegralValue() + f.FractionalValue().
    53  func (f Fixed8) FractionalValue() int32 {
    54  	return int32(int64(f) % decimals)
    55  }
    56  
    57  // Fixed8FromInt64 returns a new Fixed8 type multiplied by decimals.
    58  func Fixed8FromInt64(val int64) Fixed8 {
    59  	return Fixed8(decimals * val)
    60  }
    61  
    62  // Fixed8FromFloat returns a new Fixed8 type multiplied by decimals.
    63  func Fixed8FromFloat(val float64) Fixed8 {
    64  	return Fixed8(int64(decimals * val))
    65  }
    66  
    67  // Fixed8FromString parses s which must be a fixed point number
    68  // with precision up to 10^-8.
    69  func Fixed8FromString(s string) (Fixed8, error) {
    70  	num, err := FromString(s, precision)
    71  	if err != nil {
    72  		return 0, err
    73  	}
    74  	return Fixed8(num.Int64()), err
    75  }
    76  
    77  // UnmarshalJSON implements the json unmarshaller interface.
    78  func (f *Fixed8) UnmarshalJSON(data []byte) error {
    79  	if len(data) > 2 {
    80  		if data[0] == '"' && data[len(data)-1] == '"' {
    81  			data = data[1 : len(data)-1]
    82  		}
    83  	}
    84  	return f.setFromString(string(data))
    85  }
    86  
    87  // UnmarshalYAML implements the yaml unmarshaler interface.
    88  func (f *Fixed8) UnmarshalYAML(unmarshal func(any) error) error {
    89  	var s string
    90  	err := unmarshal(&s)
    91  	if err != nil {
    92  		return err
    93  	}
    94  	return f.setFromString(s)
    95  }
    96  
    97  func (f *Fixed8) setFromString(s string) error {
    98  	p, err := Fixed8FromString(s)
    99  	if err != nil {
   100  		return err
   101  	}
   102  	*f = p
   103  	return nil
   104  }
   105  
   106  // MarshalJSON implements the json marshaller interface.
   107  func (f Fixed8) MarshalJSON() ([]byte, error) {
   108  	return []byte(`"` + f.String() + `"`), nil
   109  }
   110  
   111  // MarshalYAML implements the yaml marshaller interface.
   112  func (f Fixed8) MarshalYAML() (any, error) {
   113  	return f.String(), nil
   114  }
   115  
   116  // DecodeBinary implements the io.Serializable interface.
   117  func (f *Fixed8) DecodeBinary(r *io.BinReader) {
   118  	*f = Fixed8(r.ReadU64LE())
   119  }
   120  
   121  // EncodeBinary implements the io.Serializable interface.
   122  func (f *Fixed8) EncodeBinary(w *io.BinWriter) {
   123  	w.WriteU64LE(uint64(*f))
   124  }
   125  
   126  // Satoshi defines the value of a 'Satoshi'.
   127  func Satoshi() Fixed8 {
   128  	return Fixed8(1)
   129  }
   130  
   131  // Div implements Fixd8 division operator.
   132  func (f Fixed8) Div(i int64) Fixed8 {
   133  	return f / Fixed8FromInt64(i)
   134  }
   135  
   136  // Add implements Fixd8 addition operator.
   137  func (f Fixed8) Add(g Fixed8) Fixed8 {
   138  	return f + g
   139  }
   140  
   141  // Sub implements Fixd8 subtraction operator.
   142  func (f Fixed8) Sub(g Fixed8) Fixed8 {
   143  	return f - g
   144  }
   145  
   146  // LessThan implements Fixd8 < operator.
   147  func (f Fixed8) LessThan(g Fixed8) bool {
   148  	return f < g
   149  }
   150  
   151  // GreaterThan implements Fixd8 < operator.
   152  func (f Fixed8) GreaterThan(g Fixed8) bool {
   153  	return f > g
   154  }
   155  
   156  // Equal implements Fixd8 == operator.
   157  func (f Fixed8) Equal(g Fixed8) bool {
   158  	return f == g
   159  }
   160  
   161  // CompareTo returns the difference between the f and g.
   162  // difference < 0 implies f < g.
   163  // difference = 0 implies f = g.
   164  // difference > 0 implies f > g.
   165  func (f Fixed8) CompareTo(g Fixed8) int {
   166  	return int(f - g)
   167  }