Ejemplo n.º 1
0
// String returns a kind messy decimal string version of this.
// It is utterly precise, and will use as many decimal digits
// as are necessary to completely represent this number.
func (f Float) String() string {
	sign := "+"
	if !f.sign {
		sign = "-"
	}

	var whole *mathx.Int
	var fraction *mathx.Int

	if f.exp <= 0 {
		whole = f.mantissa.Rsh(uint(-f.exp))
		fraction = f.mantissa.Sub(whole.Lsh(uint(-f.exp)))
	} else {
		whole = mathx.NewInt(0)
		fraction = f.mantissa
	}

	whole = f.mantissa.Rsh(uint(-f.exp))
	fraction = f.mantissa.Sub(whole.Lsh(uint(-f.exp)))

	digits := ""
	for fraction.Sign() != 0 {
		fraction = fraction.Mul64(10)
		digit := fraction.Rsh(uint(-f.exp))
		fraction = fraction.Sub(digit.Lsh(uint(-f.exp)))
		digits += digit.String()
	}
	if digits == "" {
		digits = "0"
	}
	return fmt.Sprintf("%s%s.%s", sign, whole.String(), digits)
}
Ejemplo n.º 2
0
func TestSqrt(t *testing.T) {
	numbers := []string{
		"93845895110924997939619620205961794350920309182366517272043413179685324014761",
		"69105835870199153467162210945784416638855243478241804950569679288538869324319",
		"98962852285157630260915782241836609413140230175083651803312834404919437446053",
		"36317938229605222802428943032353131143116755641174816538429154625143871344197",
		"34350266504989669203432549294422599219204587184049128615381495990495502309209",
		"18204849169635358408169482661313928794336132815120732872856773352186520943781",
		"9723547989068653705018929505866149012335913222247343211073612173133525296219",
		"82871077872852450664782155632268023043996476167345573065229622315492882980623",
		"22856450670839904203062539524939514231429034860506554613939398064780917006117",
		"1133028424325951536479152017902354822905940331016138739712579674465852496751",
		"66190348295371735778910813271715110278762226582449603965856760126883910115231",
		"67110703748429597893338674661673279865284238141342172221809893325337357465213",
		"67907826904909216076322754184715993424884161760995928759256942503051716644171",
		"76128483155619054801182538439486844205442146012173793296249561612451294050669",
		"77820156304482546934043298147893054920197524209952870273345573570345100056869",
		"114580143581984719060280282563142542662414835420671277376461092447281111712587",
	}
	for _, numStr := range numbers {
		n, _ := mathx.NewIntFromString(numStr, 10)
		m := n.Sqrt()
		m1 := m.Add(mathx.NewInt(1))
		if m.Mul(m).Cmp(n) >= 0 || m1.Mul(m1).Cmp(n) <= 0 {
			t.Errorf("Sqrt(%s) returned %s", n, m)
		}
	}
}
Ejemplo n.º 3
0
// Discriminant returns the discriminant of this polynomial.
func Discriminant(p *poly.IntPolynomial) *mathx.Int {
	if p.Degree() == 2 {
		c, b, a := p.Coeff(0), p.Coeff(1), p.Coeff(2)
		ac4 := mathx.NewInt(4).Mul(a).Mul(c)
		return b.Mul(b).Sub(ac4)
	}
	return nil
}
Ejemplo n.º 4
0
func TestFundamentalDiscriminantsSmall(t *testing.T) {
	fundamentals := []int{1, 5, 8, 12, 13, 17, 21, 24, 28, 29, 33, -3, -4, -7, -8, -11, -15, -19, -20, -23, -24, -31}
	good := mathx.NewIntSet(fundamentals)

	for d := -31; d <= 33; d++ {
		a := IsFundamentalDiscriminant(mathx.NewInt(int64(d)))
		b := good.Contains(d)
		if a != b {
			t.Errorf("Fundamental discriminant failed for ", d)
		}
	}
}
Ejemplo n.º 5
0
// NewFloat constructs a new Float from an IEEE 64-bit float64.
func NewFloat(f float64) *Float {
	x := new(Float)
	x.precision = 52
	// Convert from IEEE 754 double
	bits := math.Float64bits(f)
	s := bits >> 63
	e := int64((bits >> 52) & 0x7ff)
	m := int64(bits & uint64((int64(1)<<52)-1))
	if s == 0 && e == 0 && m == 0 {
		x.sign = false
		x.exp = 0
		x.mantissa = mathx.NewInt(0)
		return x
	}

	if s == 0 {
		x.sign = true
	}
	x.exp = e - 1023 - 52
	x.mantissa = mathx.NewInt((int64(1) << 52) | m)
	return x.normalize()
}
Ejemplo n.º 6
0
func makeFundamentalDiscriminant(D int64) int64 {
	if IsFundamentalDiscriminant(mathx.NewInt(D)) {
		return D
	}
	factors := Factorization64(D)
	for _, f := range factors {
		ex := f.exponent
		for ex >= 2 {
			D = D / (f.prime * f.prime)
			ex -= 2
		}
	}
	return D
}
Ejemplo n.º 7
0
// IsIrreducible returns true if this polynomial is irreducible.
// It currently only works on degree <= 2.
func (p *IntPolynomial) IsIrreducible() bool {
	g := &p.coeffs[0]
	if g.Sign() == 0 {
		return false
	}
	// check the gcd of the coefficients
	for _, c := range p.coeffs {
		if c.Sign() == 0 {
			continue
		}
		g = g.GCD(&c)
		if g.Cmp(intOne) == 0 {
			break
		}
	}
	if g.Cmp(intOne) != 0 {
		return false
	}
	if p.Degree() == 1 {
		return true
	}
	if p.Degree() == 2 {
		c, b, a := p.coeffs[0], p.coeffs[1], p.coeffs[2]
		b2 := b.Mul(&b)
		ac4 := mathx.NewInt(4)
		ac4 = ac4.Mul(&a)
		ac4 = ac4.Mul(&c)
		b2 = b2.Sub(ac4)
		return !mathx.IsSquare((*mathx.Int)(b2))
	}
	/*
		// check the gcd of the coefficients
		a0 := p.coeffs[0].Int64()
		g.SetInt64(a0)
		for i, c := range p.coeffs {
			if i == 0 {
				continue
			}
			if i == len(p.coeffs)-1 {
				break
			}
			if c.Sign() == 0 {
				continue
			}
			g.GCD(nil, nil, &g, &c)
		}
		if g.Cmp(intOne) != 0 {
			sufficient := true
			for _, primeExp := range Factorization64(g.Int64()) {
				p := primeExp.prime
				if a0%(p*p) == 0 {
					sufficient = false
					break
				}
			}
			if sufficient {
				return true
			}
		}
	*/
	// TODO: implement more cases
	return true
}
Ejemplo n.º 8
0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package poly

import (
	"strconv"

	"github.com/swenson/mathx"
)

var intZero = mathx.NewInt(0)
var intOne = mathx.NewInt(1)

// IntPolynomial represents an integer polynomial of arbitrary size.
type IntPolynomial struct {
	coeffs []mathx.Int
}

// NewIntPolynomial64 creates a new polynomial for the given
// coefficients (assumed to be c0, c1, ...).
func NewIntPolynomial64(coeffs ...int64) *IntPolynomial {
	p := new(IntPolynomial)
	p.coeffs = make([]mathx.Int, len(coeffs))
	for i, c := range coeffs {
		p.coeffs[i] = *mathx.NewInt(c)
	}