1
0
mirror of https://github.com/golang/go synced 2024-11-23 00:20:12 -07:00

slightly simpler math.Pow per gri's suggestion

R=gri
DELTA=28  (2 added, 9 deleted, 17 changed)
OCL=19707
CL=19707
This commit is contained in:
Russ Cox 2008-11-20 11:56:48 -08:00
parent 5014da7cb0
commit 2e7e76073a

View File

@ -6,7 +6,7 @@ package math
import "math" import "math"
// x^y: exponentation // x^y: exponentiation
export func Pow(x, y float64) float64 { export func Pow(x, y float64) float64 {
// TODO: x or y NaN, ±Inf, maybe ±0. // TODO: x or y NaN, ±Inf, maybe ±0.
switch { switch {
@ -38,7 +38,9 @@ export func Pow(x, y float64) float64 {
return Exp(y * Log(x)); return Exp(y * Log(x));
} }
ans := float64(1); // ans = a1 * 2^ae (= 1 for now).
a1 := float64(1);
ae := 0;
// ans *= x^yf // ans *= x^yf
if yf != 0 { if yf != 0 {
@ -46,42 +48,33 @@ export func Pow(x, y float64) float64 {
yf--; yf--;
yi++; yi++;
} }
ans = Exp(yf * Log(x)); a1 = Exp(yf * Log(x));
} }
// ans *= x^yi // ans *= x^yi
// by multiplying in successive squarings // by multiplying in successive squarings
// of x according to bits of yi. // of x according to bits of yi.
// accumulate powers of two into exp. // accumulate powers of two into exp.
// will still have to do ans *= 2^exp later.
x1, xe := sys.frexp(x); x1, xe := sys.frexp(x);
exp := 0; for i := int64(yi); i != 0; i >>= 1 {
if i := int64(yi); i != 0 { if i&1 == 1 {
for { a1 *= x1;
if i&1 == 1 { ae += xe;
ans *= x1; }
exp += xe; x1 *= x1;
} xe <<= 1;
i >>= 1; if x1 < .5 {
if i == 0 { x1 += x1;
break; xe--;
}
x1 *= x1;
xe <<= 1;
if x1 < .5 {
x1 += x1;
xe--;
}
} }
} }
// ans *= 2^exp // ans = a1*2^ae
// if flip { ans = 1 / ans } // if flip { ans = 1 / ans }
// but in the opposite order // but in the opposite order
if flip { if flip {
ans = 1 / ans; a1 = 1 / a1;
exp = -exp; ae = -ae;
} }
return sys.ldexp(ans, exp); return sys.ldexp(a1, ae);
} }