github.com/seeker-insurance/kit@v0.0.13/pretty/text/cmd/agg/num.go (about)

     1  package main
     2  
     3  import (
     4  	"math/big"
     5  	"strconv"
     6  )
     7  
     8  func min(s, arg string) agg { return newBinop(s, opmin) }
     9  func max(s, arg string) agg { return newBinop(s, opmax) }
    10  func sum(s, arg string) agg { return newBinop(s, opsum) }
    11  
    12  type binop struct {
    13  	v *big.Float
    14  	f func(a, b *big.Float) *big.Float
    15  }
    16  
    17  func newBinop(s string, f func(a, b *big.Float) *big.Float) *binop {
    18  	v, _ := parseFloat(s)
    19  	return &binop{v, f}
    20  }
    21  
    22  func (o *binop) String() string {
    23  	if o.v == nil {
    24  		return "NaN"
    25  	}
    26  	return o.v.Text('f', -1)
    27  }
    28  
    29  func (o *binop) merge(s string) {
    30  	v, ok := parseFloat(s)
    31  	if !ok {
    32  		return
    33  	}
    34  	o.v = o.f(o.v, v)
    35  }
    36  
    37  func opmin(a, b *big.Float) *big.Float {
    38  	if a != nil && (b == nil || a.Cmp(b) <= 0) {
    39  		return a
    40  	}
    41  	return b
    42  }
    43  
    44  func opmax(a, b *big.Float) *big.Float {
    45  	if a != nil && (b == nil || a.Cmp(b) >= 0) {
    46  		return a
    47  	}
    48  	return b
    49  }
    50  
    51  func opsum(a, b *big.Float) *big.Float {
    52  	if a == nil {
    53  		return b
    54  	} else if b == nil {
    55  		return a
    56  	}
    57  	return a.Add(a, b)
    58  }
    59  
    60  type meanagg struct {
    61  	v *big.Float
    62  	d float64 // actually an integer
    63  }
    64  
    65  func mean(s, arg string) agg {
    66  	v, ok := parseFloat(s)
    67  	if !ok {
    68  		return &meanagg{new(big.Float), 0}
    69  	}
    70  	return &meanagg{v, 1}
    71  }
    72  
    73  func (m *meanagg) String() string {
    74  	if m.d == 0 {
    75  		return "NaN"
    76  	}
    77  	v := new(big.Float).Quo(m.v, big.NewFloat(m.d))
    78  	return v.Text('f', -1)
    79  }
    80  
    81  func (m *meanagg) merge(s string) {
    82  	v, ok := parseFloat(s)
    83  	if !ok {
    84  		return
    85  	}
    86  	m.v.Add(m.v, v)
    87  	m.d++
    88  }
    89  
    90  func parseFloat(s string) (*big.Float, bool) {
    91  	v, _, err := big.ParseFloat(s, 0, 1000, big.ToNearestEven)
    92  	return v, err == nil
    93  }
    94  
    95  type counter int
    96  
    97  func count(init, arg string) agg  { return new(counter) }
    98  func (c *counter) String() string { return strconv.Itoa(int(*c) + 1) }
    99  func (c *counter) merge(string)   { *c++ }