// toRat returns the fraction corresponding to x, or nil // if x cannot be represented as a fraction a/b because // its components a or b are too large. func toRat(x *big.Float) *big.Rat { m := newFloat() e := x.MantExp(m) // fail to convert if fraction components are too large if e <= maxExp || e >= maxExp { return nil } // convert mantissa to big.Int value by shifting by ecorr ecorr := int(m.MinPrec()) a, _ := m.SetMantExp(m, ecorr).Int(nil) e -= ecorr // correct exponent // compute actual fraction b := big.NewInt(1) switch { case e < 0: b.Lsh(b, uint(-e)) case e > 0: a.Lsh(a, uint(e)) } return new(big.Rat).SetFrac(a, b) }
func makeFloat(x *big.Float) Value { // convert -0 if x.Sign() == 0 { return floatVal0 } return floatVal{x} }
// Subtract func (a Scalar) Sub_S(b S) S { var x, y big.Float x = big.Float(a) y = big.Float(b.(Scalar)) z := x.Sub(&x, &y) return (Scalar)(*z) }
// Divide func (a Scalar) Div_S(b S) S { var x, y big.Float x = big.Float(a) y = big.Float(b.(Scalar)) z := x.Quo(&x, &y) return (Scalar)(*z) }
func (m *meanagg) String() string { if m.d == 0 { return "NaN" } v := new(big.Float).Quo(m.v, big.NewFloat(m.d)) return v.Text('f', -1) }
func arithDivide(a, b *big.Float) (*big.Float, error) { i, acc := b.Int64() if acc == big.Exact && i == 0 { return nil, fmt.Errorf("divide: by zero") } return new(big.Float).Quo(a, b), nil }
func (sed StringEncoderDecoder) Encode(w io.Writer, n *big.Float) error { // TODO - big.Float.MarshalText? // TODO - big.Float.Append str := []byte(n.Text('g', -1)) _, err := w.Write(str) return err }
// Add func (a Scalar) Add_S(b S) S { var x, y big.Float x = big.Float(a) y = big.Float(b.(Scalar)) z := x.Add(&x, &y) return (Scalar)(*z) }
// floatSqrt computes the square root of x using Newton's method. // TODO: Use a better algorithm such as the one from math/sqrt.go. func floatSqrt(c Context, x *big.Float) *big.Float { switch x.Sign() { case -1: Errorf("square root of negative number") case 0: return newFloat(c) } // Each iteration computes // z = z - (z²-x)/2z // z holds the result so far. A good starting point is to halve the exponent. // Experiments show we converge in only a handful of iterations. z := newFloat(c) exp := x.MantExp(z) z.SetMantExp(z, exp/2) // Intermediates, allocated once. zSquared := newFloat(c) num := newFloat(c) den := newFloat(c) for loop := newLoop(c.Config(), "sqrt", x, 1); ; { zSquared.Mul(z, z) num.Sub(zSquared, x) den.Mul(floatTwo, z) num.Quo(num, den) z.Sub(z, num) if loop.done(z) { break } } return z }
// smallRat reports whether x would lead to "reasonably"-sized fraction // if converted to a *big.Rat. func smallRat(x *big.Float) bool { if !x.IsInf() { e := x.MantExp(nil) return -maxExp < e && e < maxExp } return false }
func fconv(fvp *Mpflt, flag FmtFlag) string { if flag&FmtSharp == 0 { return fvp.Val.Text('b', 0) } // use decimal format for error messages // determine sign f := &fvp.Val var sign string if f.Sign() < 0 { sign = "-" f = new(big.Float).Abs(f) } else if flag&FmtSign != 0 { sign = "+" } // Don't try to convert infinities (will not terminate). if f.IsInf() { return sign + "Inf" } // Use exact fmt formatting if in float64 range (common case): // proceed if f doesn't underflow to 0 or overflow to inf. if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) { return fmt.Sprintf("%s%.6g", sign, x) } // Out of float64 range. Do approximate manual to decimal // conversion to avoid precise but possibly slow Float // formatting. // f = mant * 2**exp var mant big.Float exp := f.MantExp(&mant) // 0.5 <= mant < 1.0 // approximate float64 mantissa m and decimal exponent d // f ~ m * 10**d m, _ := mant.Float64() // 0.5 <= m < 1.0 d := float64(exp) * (math.Ln2 / math.Ln10) // log_10(2) // adjust m for truncated (integer) decimal exponent e e := int64(d) m *= math.Pow(10, d-float64(e)) // ensure 1 <= m < 10 switch { case m < 1-0.5e-6: // The %.6g format below rounds m to 5 digits after the // decimal point. Make sure that m*10 < 10 even after // rounding up: m*10 + 0.5e-5 < 10 => m < 1 - 0.5e6. m *= 10 e-- case m >= 10: m /= 10 e++ } return fmt.Sprintf("%s%.6ge%+d", sign, m, e) }
func opsum(a, b *big.Float) *big.Float { if a == nil { return b } else if b == nil { return a } return a.Add(a, b) }
// Multiply func (a Scalar) Mul_S(b S) S { var x, y big.Float x = big.Float(a) y = big.Float(b.(Scalar)) z := x.Mul(&x, &y) return (Scalar)(*z) }
func (bed BinaryEncoderDecoder) Encode(w io.Writer, n *big.Float) error { exponent := n.MantExp(bed.tmp) f, _ := bed.tmp.Float64() if err := binary.Write(w, binary.BigEndian, f); err != nil { return err } return binary.Write(w, binary.BigEndian, int32(exponent)) }
// Returns pi using Machin's formula func pi(prec uint, result *big.Float) { var tmp, _4 big.Float _4.SetPrec(prec).SetInt64(4) acot(prec, 5, &tmp) tmp.SetPrec(prec).Mul(&tmp, &_4) acot(prec, 239, result) result.Sub(&tmp, result) result.SetPrec(prec).Mul(result, &_4) }
func arithRound(a *big.Float) (*big.Float, error) { var i *big.Int if a.Signbit() { i, _ = new(big.Float).Sub(a, halfAwayFromZero).Int(nil) } else { i, _ = new(big.Float).Add(a, halfAwayFromZero).Int(nil) } return new(big.Float).SetInt(i), nil }
func TestDecodeBigReal(t *testing.T) { var hugeFloat big.Float hugeFloat.SetString("3.14e+99999") data := fmt.Sprintf("<real>%s</real>", hugeFloat.String()) decoder := baseDecoder{nil, xml.NewDecoder(bytes.NewReader([]byte(data)))} value, err := decoder.NextValue() assert.NoError(t, err) assert.Equal(t, hugeFloat, value) }
func TestPow(t *testing.T) { for _, test := range []struct { z, w string want string }{ {"1.5", "1.5", "1.8371173070873835736479630560294185439744606104925025963245194254382202830929862699048945748284801761139459509199606418436441490948783180062193379634279589146216845606457574284357225789531838276676109830092400181402243325144092030253566067045309391758849310432709781082027026621306513787250611923558785098172755465204952231278685708006003328040156619"}, {"2", "1.5", "2.8284271247461900976033774484193961571393437507538961463533594759814649569242140777007750686552831454700276924618245940498496721117014744252882429941998716628264453318550111855115999010023055641211429402191199432119405490691937240294570348372817783972191046584609686174286429016795252072559905028159793745067930926636176592812412305167047901094915006"}, {"1.5", "-1.5", "0.54433105395181735515495201660130919821465499570148225076282057050021341721273667256441320735658671884857657805035870869441308121329727940925017421138606190062864727722837257138836224561575817116077362459533037574525165407834346756306862420874990790396590549430251203206006004803871151962224035329063066957548905082088747351936846542240009860859723315"}, {"2", "-1.5", "0.35355339059327376220042218105242451964241796884423701829416993449768311961552675971259688358191039318375346155772807425623120901396268430316103037427498395785330566648187639818894998762528819551514286752738999290149256863364921550368212935466022229965238808230762107717858036270994065090699881285199742181334913658295220741015515381458809876368643757"}, } { for _, prec := range []uint{24, 53, 64, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000} { want := new(big.Float).SetPrec(prec) want.Parse(test.want, 10) z := new(big.Float).SetPrec(prec) z.Parse(test.z, 10) w := new(big.Float).SetPrec(prec) w.Parse(test.w, 10) x := bigfloat.Pow(z, w) if x.Cmp(want) != 0 { t.Errorf("prec = %d, Pow(%v, %v) =\ngot %g;\nwant %g", prec, test.z, test.w, x, want) } } } }
func TestPowIntegers(t *testing.T) { for _, test := range []struct { z, w string want string }{ {"2", "5", "32"}, {"2", "10", "1024"}, {"2", "64", "18446744073709551616"}, {"2", "-5", "0.03125"}, {"2", "-10", "0.0009765625"}, {"2", "-64", "5.42101086242752217003726400434970855712890625e-20"}, {"1.5", "8", "25.62890625"}, } { for _, prec := range []uint{24, 53, 64, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000} { want := new(big.Float).SetPrec(prec) want.Parse(test.want, 10) z := new(big.Float).SetPrec(prec) z.Parse(test.z, 10) w := new(big.Float).SetPrec(prec) w.Parse(test.w, 10) x := bigfloat.Pow(z, w) if x.Cmp(want) != 0 { t.Errorf("prec = %d, Pow(%v, %v) =\ngot %g;\nwant %g", prec, test.z, test.w, x, want) } } } }
func splitRangeString(start, end string, splits int) []string { results := []string{start} if start == end { return results } if end < start { tmp := start start = end end = tmp } // find longest common prefix between strings minLen := len(start) if len(end) < minLen { minLen = len(end) } prefix := "" for i := 0; i < minLen; i++ { if start[i] == end[i] { prefix = start[0 : i+1] } else { break } } // remove prefix from strings to split start = start[len(prefix):] end = end[len(prefix):] ordStart := stringToOrd(start) ordEnd := stringToOrd(end) tmp := new(big.Int) tmp.Sub(ordEnd, ordStart) stride := new(big.Float) stride.SetInt(tmp) stride.Quo(stride, big.NewFloat(float64(splits))) for i := 1; i <= splits; i++ { tmp := new(big.Float) tmp.Mul(stride, big.NewFloat(float64(i))) tmp.Add(tmp, new(big.Float).SetInt(ordStart)) result, _ := tmp.Int(new(big.Int)) value := prefix + ordToString(result, 0) if value != results[len(results)-1] { results = append(results, value) } } return results }
func TestAgm(t *testing.T) { for _, test := range []struct { a, b string want string }{ // 350 decimal digits are enough to give us up to 1000 binary digits {"1", "2", "1.4567910310469068691864323832650819749738639432213055907941723832679264545802509002574737128184484443281894018160367999355762430743401245116912132499522793768970211976726893728266666782707432902072384564600963133367494416649516400826932239086263376738382410254887262645136590660408875885100466728130947439789355129117201754471869564160356411130706061"}, {"1", "10", "4.2504070949322748617281643183731348667984678641901928596701476622237553127409037845252854607876171790458817135897668652366410690187825866854343005714304399718866701345600268795095037823053677248108795697049522041225723229732458947507697835936406527028150257238518982793084569470658500853106997941082919334694146843915361847332301248942222685517896377"}, {"1", "0.125", "0.45196952219967034359164911331276507645541557018306954112635037493237190371123433961098897571407153216488726488616781446636283304514042965741376539315003644325377859387794608118242990700589889155408232061013871480906595147189700268152276449512798584772002737950386745259435790965051247641106770187776231088478906739003673011639874297764052324720923824"}, {"1", "0.00390625", "0.2266172673264813935990249059047521131153183423554951008357647589399579243281007098800682366778894106068183449922373565084840603788091294841822891406755449218057751291845474188560350241555526734834267320629182988862200822134426714354129001630331838172767684623648755579758508073234772093745831056731263684472818466567279847347734121500617411676068370"}, {"1", "0.0001220703125", "0.15107867088555894565277006051956059212554039802503247524478909254186086852737399490629222674071181480492157167137547694132610166031526264375084434300568336411139925857454913414480542768807718797335060713475211709310835676172131569048902323084439330888400622327072954342544508199547787750415198261456314278054748992781108231991187512975110547417178045"}, } { for _, prec := range []uint{24, 53, 64, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000} { want := new(big.Float).SetPrec(prec) want.Parse(test.want, 10) a := new(big.Float).SetPrec(prec) a.Parse(test.a, 10) b := new(big.Float).SetPrec(prec) b.Parse(test.b, 10) z := agm(a, b) if z.Cmp(want) != 0 { t.Errorf("prec = %d, Agm(%v, %v) =\ngot %g;\nwant %g", prec, test.a, test.b, z, want) } } } }
func compareJSONNumber(a, b json.Number) int { bigA, ok := new(big.Float).SetString(string(a)) if !ok { panic("illegal value") } bigB, ok := new(big.Float).SetString(string(b)) if !ok { panic("illegal value") } return bigA.Cmp(bigB) }
func TestRoot(t *testing.T) { x := big.NewFloat(0.12381245613960218386) n := 16 res := Root(x, n) exp := big.NewFloat(0.8776023372475015) diff := new(big.Float).Sub(res, exp) diff = diff.Abs(diff) if diff.Cmp(big.NewFloat(0.00000001)) >= 0 { log.Fatal("Exp failed:", exp, res) } }
func TestPow(t *testing.T) { x := big.NewFloat(0.12381245613960218386) n := 3 res := Pow(x, n) exp := big.NewFloat(0.00189798605) diff := new(big.Float).Sub(res, exp) diff = diff.Abs(diff) if diff.Cmp(big.NewFloat(0.00000001)) >= 0 { log.Fatal("Pow failed:", exp, res) } }
func (bed BinaryVarintEncoderDecoder) Decode(r io.Reader, n *big.Float) error { var isInteger int8 var f float64 var exponent int32 n.SetUint64(0) if err := binary.Read(r, binary.BigEndian, &isInteger); err != nil { return err } if isInteger <= 0 { var x int64 var err error if x, err = binary.ReadVarint(miniByteReader{r}); err != nil { return err } n.SetInt64(x) n.SetPrec(ENCODER_DECODER_PREC) return nil } else { if err := binary.Read(r, binary.BigEndian, &f); err != nil { return err } if err := binary.Read(r, binary.BigEndian, &exponent); err != nil { return err } bed.tmp.SetFloat64(f) bed.tmp.SetPrec(ENCODER_DECODER_PREC) n.SetMantExp(bed.tmp, int(exponent)) return nil } }
func (bed BinaryEncoderDecoder) Decode(r io.Reader, n *big.Float) error { var f float64 var exponent int32 n.SetUint64(0) if err := binary.Read(r, binary.BigEndian, &f); err != nil { return err } if err := binary.Read(r, binary.BigEndian, &exponent); err != nil { return err } bed.tmp.SetFloat64(f) bed.tmp.SetPrec(ENCODER_DECODER_PREC) n.SetMantExp(bed.tmp, int(exponent)) return nil }
func TestPi(t *testing.T) { enablePiCache = false piStr := "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153644" for _, prec := range []uint{24, 53, 64, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000} { want := new(big.Float).SetPrec(prec) want.Parse(piStr, 10) z := pi(prec) if z.Cmp(want) != 0 { t.Errorf("Pi(%d) =\ngot %g;\nwant %g", prec, z, want) } } enablePiCache = true }
func withinMandLimit(z *BigComplex, limit *big.Float) bool { // Approximate cmplx.Abs negLimit := MakeBigFloat(0.0, limit.Prec()) negLimit.Neg(limit) r := z.Real() i := z.Imag() rLimCmp := r.Cmp(limit) rNegLimCmp := r.Cmp(&negLimit) iLimCmp := i.Cmp(limit) iNegLimCmp := i.Cmp(&negLimit) within := rLimCmp == -1 && rNegLimCmp == 1 within = within && iLimCmp == -1 && iNegLimCmp == 1 return within }
// String returns returns a decimal approximation of the Float value. func (x floatVal) String() string { f := x.val // Don't try to convert infinities (will not terminate). if f.IsInf() { return f.String() } // Use exact fmt formatting if in float64 range (common case): // proceed if f doesn't underflow to 0 or overflow to inf. if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) { return fmt.Sprintf("%.6g", x) } // Out of float64 range. Do approximate manual to decimal // conversion to avoid precise but possibly slow Float // formatting. // f = mant * 2**exp var mant big.Float exp := f.MantExp(&mant) // 0.5 <= |mant| < 1.0 // approximate float64 mantissa m and decimal exponent d // f ~ m * 10**d m, _ := mant.Float64() // 0.5 <= |m| < 1.0 d := float64(exp) * (math.Ln2 / math.Ln10) // log_10(2) // adjust m for truncated (integer) decimal exponent e e := int64(d) m *= math.Pow(10, d-float64(e)) // ensure 1 <= |m| < 10 switch am := math.Abs(m); { case am < 1-0.5e-6: // The %.6g format below rounds m to 5 digits after the // decimal point. Make sure that m*10 < 10 even after // rounding up: m*10 + 0.5e-5 < 10 => m < 1 - 0.5e6. m *= 10 e-- case am >= 10: m /= 10 e++ } return fmt.Sprintf("%.6ge%+d", m, e) }
func (p *exporter) float(x *Mpflt) { // extract sign (there is no -0) f := &x.Val sign := f.Sign() if sign == 0 { // x == 0 p.int(0) return } // x != 0 // extract exponent such that 0.5 <= m < 1.0 var m big.Float exp := f.MantExp(&m) // extract mantissa as *big.Int // - set exponent large enough so mant satisfies mant.IsInt() // - get *big.Int from mant m.SetMantExp(&m, int(m.MinPrec())) mant, acc := m.Int(nil) if acc != big.Exact { Fatalf("exporter: internal error") } p.int(sign) p.int(exp) p.string(string(mant.Bytes())) }