diff --git a/utils/bignum/eval.go b/utils/bignum/eval.go index 854bba5..cf25e11 100644 --- a/utils/bignum/eval.go +++ b/utils/bignum/eval.go @@ -7,8 +7,8 @@ import ( // MonomialEval evaluates y = sum x^i * poly[i]. func MonomialEval(x *big.Float, poly []*big.Float) (y *big.Float) { n := len(poly) - 1 - y = new(big.Float).Set(poly[n-1]) - for i := n - 2; i >= 0; i-- { + y = new(big.Float).Set(poly[n]) + for i := n - 1; i >= 0; i-- { y.Mul(y, x) y.Add(y, poly[i]) } diff --git a/utils/bignum/eval_test.go b/utils/bignum/eval_test.go new file mode 100644 index 0000000..5fc44c0 --- /dev/null +++ b/utils/bignum/eval_test.go @@ -0,0 +1,24 @@ +package bignum + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestMonomialEval(t *testing.T) { + newFloat := func(f float64) *big.Float { return new(big.Float).SetPrec(53).SetFloat64(f) } + + // 1 + 2x at x = 3 = 7: the highest-degree coefficient must not be dropped. + got := MonomialEval(newFloat(3), []*big.Float{newFloat(1), newFloat(2)}) + require.Zerof(t, got.Cmp(newFloat(7)), "1 + 2x at x=3: got %v, want 7", got) + + // 1 + 2x + 3x^2 at x = 2 = 17. + got = MonomialEval(newFloat(2), []*big.Float{newFloat(1), newFloat(2), newFloat(3)}) + require.Zerof(t, got.Cmp(newFloat(17)), "1 + 2x + 3x^2 at x=2: got %v, want 17", got) + + // A constant polynomial must return the constant without panicking. + got = MonomialEval(newFloat(9), []*big.Float{newFloat(5)}) + require.Zerof(t, got.Cmp(newFloat(5)), "constant poly: got %v, want 5", got) +}