Newton's algorithm for a polynomial of arbitary degree Improvement over the last one I posted (now deleted, had no answers and was only cubics). Uses Horner's algorithm this time...

package main

import (
    "fmt"
    "math"
)

const ε float64 = 0.01

type polynomial struct {
    coeffs []float64
    x      float64
}

// Both of these functions use Horner's algorithm

func evalPoly(p polynomial, n int) float64 {
    var result float64 = 0
    for i := 0; i &lt; n; i++ {
        result = result*p.x + p.coeffs[i]
    }
    return result
}

func evalPolyDeriv(p polynomial, n int) float64 {
    var result float64 = 0
    for i := 0; i &lt; n-1; i++ {
        result = result*p.x + float64(n-i-1)*p.coeffs[i]
    }
    return result
}

func f(p polynomial) float64 {
    return evalPoly(p, len(p.coeffs)) / evalPolyDeriv(p, len(p.coeffs))
}

func solveNewton(p polynomial) float64 {
    h := f(p)
    for math.Abs(h) &gt;= ε {
        p.x -= h
        h = f(p)
    }
    return p.x - h
}

func main() {
    guess := float64(2)
    coeffs := []float64{1, -2, 1, -4} // Can be of arbitary length
    fmt.Println(solveNewton(polynomial{coeffs: coeffs, x: guess})) // 2.3146...
}
In general, LGTM. Few notes:


The name f is meaningless. newtonDelta perhaps?
It feels right to compute a derivative's coefficients once, and reuse evalPoly for both the function and its derivative. After all, the polynomial's derivative is also polynomial. There is an usual space-time tradeoff, but in the case of polynomials DRY rule casts a deciding vote.
Newton's algorithm does not necessarily converge. You should be prepared to handle the divergent case.
Hardcoding ε is dubious. I recommend to solveNewton have it as a parameter.
Using Horner schedule is a definite improvement.