本文整理汇总了Golang中math/big.Float.MantExp方法的典型用法代码示例。如果您正苦于以下问题:Golang Float.MantExp方法的具体用法?Golang Float.MantExp怎么用?Golang Float.MantExp使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类math/big.Float
的用法示例。
在下文中一共展示了Float.MantExp方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: floatSqrt
// 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
}
示例2: smallRat
// 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
}
示例3: toRat
// 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)
}
示例4: floatLog
// floatLog computes natural log(x) using the Maclaurin series for log(1-x).
func floatLog(x *big.Float) *big.Float {
if x.Sign() <= 0 {
Errorf("log of non-positive value")
}
// The series wants x < 1, and log 1/x == -log x, so exploit that.
invert := false
if x.Cmp(floatOne) > 0 {
invert = true
xx := newF()
xx.Quo(floatOne, x)
x = xx
}
// x = mantissa * 2**exp, and 0.5 <= mantissa < 1.
// So log(x) is log(mantissa)+exp*log(2), and 1-x will be
// between 0 and 0.5, so the series for 1-x will converge well.
// (The series converges slowly in general.)
mantissa := newF()
exp2 := x.MantExp(mantissa)
exp := newF().SetInt64(int64(exp2))
exp.Mul(exp, floatLog2)
if invert {
exp.Neg(exp)
}
// y = 1-x (whereupon x = 1-y and we use that in the series).
y := newF().SetInt64(1)
y.Sub(y, mantissa)
// The Maclaurin series for log(1-y) == log(x) is: -y - y²/2 - y³/3 ...
yN := newF().Set(y)
term := newF()
n := newF().Set(floatOne)
z := newF()
// This is the slowest-converging series, so we add a factor of ten to the cutoff.
// Only necessary when FloatPrec is at or beyond constPrecisionInBits.
loop := newLoop("log", y, 40)
for {
term.Set(yN)
term.Quo(term, n)
z.Sub(z, term)
if loop.terminate(z) {
break
}
// Advance y**index (multiply by y).
yN.Mul(yN, y)
n.Add(n, floatOne)
}
if invert {
z.Neg(z)
}
z.Add(z, exp)
return z
}
示例5: Encode
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))
}
示例6: Sqrt
// Sqrt returns a big.Float representation of the square root of
// z. Precision is the same as the one of the argument. The function
// panics if z is negative, returns ±0 when z = ±0, and +Inf when z =
// +Inf.
func Sqrt(z *big.Float) *big.Float {
// panic on negative z
if z.Sign() == -1 {
panic("Sqrt: argument is negative")
}
// √±0 = ±0
if z.Sign() == 0 {
return big.NewFloat(float64(z.Sign()))
}
// √+Inf = +Inf
if z.IsInf() {
return big.NewFloat(math.Inf(+1))
}
// Compute √(a·2**b) as
// √(a)·2**b/2 if b is even
// √(2a)·2**b/2 if b > 0 is odd
// √(0.5a)·2**b/2 if b < 0 is odd
//
// The difference in the odd exponent case is due to the fact that
// exp/2 is rounded in different directions when exp is negative.
mant := new(big.Float)
exp := z.MantExp(mant)
switch exp % 2 {
case 1:
mant.Mul(big.NewFloat(2), mant)
case -1:
mant.Mul(big.NewFloat(0.5), mant)
}
// Solving x² - z = 0 directly requires a Quo call, but it's
// faster for small precisions.
//
// Solving 1/x² - z = 0 avoids the Quo call and is much faster for
// high precisions.
//
// Use sqrtDirect for prec <= 128 and sqrtInverse for prec > 128.
var x *big.Float
if z.Prec() <= 128 {
x = sqrtDirect(mant)
} else {
x = sqrtInverse(mant)
}
// re-attach the exponent and return
return x.SetMantExp(x, exp/2)
}
示例7: float
func (p *exporter) float(x constant.Value) {
if x.Kind() != constant.Float {
log.Fatalf("gcimporter: unexpected constant %v, want float", x)
}
// extract sign (there is no -0)
sign := constant.Sign(x)
if sign == 0 {
// x == 0
p.int(0)
return
}
// x != 0
var f big.Float
if v, exact := constant.Float64Val(x); exact {
// float64
f.SetFloat64(v)
} else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
// TODO(gri): add big.Rat accessor to constant.Value.
r := valueToRat(num)
f.SetRat(r.Quo(r, valueToRat(denom)))
} else {
// Value too large to represent as a fraction => inaccessible.
// TODO(gri): add big.Float accessor to constant.Value.
f.SetFloat64(math.MaxFloat64) // FIXME
}
// 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 {
log.Fatalf("gcimporter: internal error")
}
p.int(sign)
p.int(exp)
p.string(string(mant.Bytes()))
}
示例8: Encode
func (bed BinaryIntEncoderDecoder) Encode(w io.Writer, n *big.Float) error {
if n.IsInt() {
x, _ := n.Int64()
// TODO - if accuracy is not Exact, then use the other path
if err := binary.Write(w, binary.BigEndian, int8(0)); err != nil {
return err
}
return binary.Write(w, binary.BigEndian, x)
} else {
if err := binary.Write(w, binary.BigEndian, int8(1)); err != nil {
return err
}
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))
}
}
示例9: floatSqrt
// 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(x *big.Float) *big.Float {
switch x.Sign() {
case -1:
Errorf("square root of negative number")
case 0:
return newF()
}
// Each iteration computes
// z = z - (z²-x)/2z
// delta holds the difference between the result
// this iteration and the previous. The loop stops
// when it hits zero.
// 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 := newF()
exp := x.MantExp(z)
z.SetMantExp(z, exp/2)
// Intermediates, allocated once.
zSquared := newF()
num := newF()
den := newF()
loop := newLoop("sqrt", x, 1)
for {
zSquared.Mul(z, z)
num.Sub(zSquared, x)
den.Mul(floatTwo, z)
num.Quo(num, den)
z.Sub(z, num)
if loop.terminate(z) {
break
}
}
return z
}
示例10: powInt
// fast path for z**w when w is an integer
func powInt(z *big.Float, w int) *big.Float {
// get mantissa and exponent of z
mant := new(big.Float)
exp := z.MantExp(mant)
// result's exponent
exp = exp * w
// result's mantissa
x := big.NewFloat(1).SetPrec(z.Prec())
// Classic right-to-left binary exponentiation
for w > 0 {
if w%2 == 1 {
x.Mul(x, mant)
}
w >>= 1
mant.Mul(mant, mant)
}
return new(big.Float).SetMantExp(x, exp)
}
示例11: Encode
func (bed BinaryVarintEncoderDecoder) Encode(w io.Writer, n *big.Float) error {
if n.IsInt() {
x, _ := n.Int64()
// TODO - if accuracy is not Exact, then use the other path
buf := make([]byte, binary.MaxVarintLen64)
nBytes := binary.PutVarint(buf, x)
if _, err := w.Write([]byte{byte(0)}); err != nil {
return err
}
_, err := w.Write(buf[0:nBytes])
return err
} else {
if err := binary.Write(w, binary.BigEndian, int8(1)); err != nil {
return err
}
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))
}
}