github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/util/math/expneg.go (about) 1 package math 2 3 import ( 4 "math/big" 5 ) 6 7 var ( 8 // Coefficents in Q.128 format 9 expNumCoef []*big.Int 10 expDenoCoef []*big.Int 11 ) 12 13 func init() { 14 15 // parameters are in integer format, 16 // coefficients are *2^-128 of that 17 // so we can just load them if we treat them as Q.128 18 num := []string{ 19 "-648770010757830093818553637600", 20 "67469480939593786226847644286976", 21 "-3197587544499098424029388939001856", 22 "89244641121992890118377641805348864", 23 "-1579656163641440567800982336819953664", 24 "17685496037279256458459817590917169152", 25 "-115682590513835356866803355398940131328", 26 "340282366920938463463374607431768211456", 27 } 28 expNumCoef = Parse(num) 29 30 deno := []string{ 31 "1225524182432722209606361", 32 "114095592300906098243859450", 33 "5665570424063336070530214243", 34 "194450132448609991765137938448", 35 "5068267641632683791026134915072", 36 "104716890604972796896895427629056", 37 "1748338658439454459487681798864896", 38 "23704654329841312470660182937960448", 39 "259380097567996910282699886670381056", 40 "2250336698853390384720606936038375424", 41 "14978272436876548034486263159246028800", 42 "72144088983913131323343765784380833792", 43 "224599776407103106596571252037123047424", 44 "340282366920938463463374607431768211456", 45 } 46 expDenoCoef = Parse(deno) 47 } 48 49 // ExpNeg accepts x in Q.128 format and computes e^-x. 50 // It is most precise within [0, 1.725) range, where error is less than 3.4e-30. 51 // Over the [0, 5) range its error is less than 4.6e-15. 52 // Output is in Q.128 format. 53 func ExpNeg(x *big.Int) *big.Int { 54 // exp is approximated by rational function 55 // polynomials of the rational function are evaluated using Horner's method 56 num := Polyval(expNumCoef, x) // Q.128 57 deno := Polyval(expDenoCoef, x) // Q.128 58 59 num = num.Lsh(num, Precision128) // Q.256 60 return num.Div(num, deno) // Q.256 / Q.128 => Q.128 61 }