github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/util/math/polyval.go (about)

     1  package math
     2  
     3  import "math/big"
     4  
     5  // note: all coefficients for which Polyval is used would need to be updated if this precision changes
     6  const Precision128 = 128
     7  
     8  // polyval evaluates a polynomial given by coefficients `p` in Q.128 format
     9  // at point `x` in Q.128 format. Output is in Q.128.
    10  // Coefficients should be ordered from the highest order coefficient to the lowest.
    11  func Polyval(p []*big.Int, x *big.Int) *big.Int {
    12  	// evaluation using Horner's method
    13  	res := new(big.Int).Set(p[0]) // Q.128
    14  	tmp := new(big.Int)           // big.Int.Mul doesn't like when input is reused as output
    15  	for _, c := range p[1:] {
    16  		tmp = tmp.Mul(res, x)            // Q.128 * Q.128 => Q.256
    17  		res = res.Rsh(tmp, Precision128) // Q.256 >> 128 => Q.128
    18  		res = res.Add(res, c)
    19  	}
    20  
    21  	return res
    22  }