From 27493187ed98cbf4f7679a5480fb84a63ece3e40 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Fri, 6 Apr 2018 09:44:29 -0700 Subject: [PATCH] cmd/compile: change cmplx{mpy,div} into Mpcplx methods MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Passes toolstash-check. Change-Id: Icae55fe4fa1bb8e4f2f83b7c69e08d30a5559d9e Reviewed-on: https://go-review.googlesource.com/105047 Run-TryBot: Matthew Dempsky Reviewed-by: Daniel Martí TryBot-Result: Gobot Gobot --- src/cmd/compile/internal/gc/const.go | 96 +------------------------- src/cmd/compile/internal/gc/mpfloat.go | 71 +++++++++++++++++++ 2 files changed, 73 insertions(+), 94 deletions(-) diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go index 27ede4b4ad..e4bbfe876d 100644 --- a/src/cmd/compile/internal/gc/const.go +++ b/src/cmd/compile/internal/gc/const.go @@ -1014,10 +1014,10 @@ func evconst(n *Node) { v.U.(*Mpcplx).Imag.Sub(&rv.U.(*Mpcplx).Imag) case OMUL_ | CTCPLX_: - cmplxmpy(v.U.(*Mpcplx), rv.U.(*Mpcplx)) + v.U.(*Mpcplx).Mul(rv.U.(*Mpcplx)) case ODIV_ | CTCPLX_: - if !cmplxdiv(v.U.(*Mpcplx), rv.U.(*Mpcplx)) { + if !v.U.(*Mpcplx).Div(rv.U.(*Mpcplx)) { yyerror("complex division by zero") rv.U.(*Mpcplx).Real.SetFloat64(1.0) rv.U.(*Mpcplx).Imag.SetFloat64(0.0) @@ -1522,98 +1522,6 @@ func nonnegintconst(n *Node) int64 { return vi.Int64() } -// complex multiply v *= rv -// (a, b) * (c, d) = (a*c - b*d, b*c + a*d) -func cmplxmpy(v *Mpcplx, rv *Mpcplx) { - var ac Mpflt - var bd Mpflt - var bc Mpflt - var ad Mpflt - - ac.Set(&v.Real) - ac.Mul(&rv.Real) // ac - - bd.Set(&v.Imag) - - bd.Mul(&rv.Imag) // bd - - bc.Set(&v.Imag) - - bc.Mul(&rv.Real) // bc - - ad.Set(&v.Real) - - ad.Mul(&rv.Imag) // ad - - v.Real.Set(&ac) - - v.Real.Sub(&bd) // ac-bd - - v.Imag.Set(&bc) - - v.Imag.Add(&ad) // bc+ad -} - -// complex divide v /= rv -// (a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d) -func cmplxdiv(v *Mpcplx, rv *Mpcplx) bool { - if rv.Real.CmpFloat64(0) == 0 && rv.Imag.CmpFloat64(0) == 0 { - return false - } - - var ac Mpflt - var bd Mpflt - var bc Mpflt - var ad Mpflt - var cc_plus_dd Mpflt - - cc_plus_dd.Set(&rv.Real) - - cc_plus_dd.Mul(&rv.Real) // cc - - ac.Set(&rv.Imag) - - ac.Mul(&rv.Imag) // dd - - cc_plus_dd.Add(&ac) // cc+dd - - // We already checked that c and d are not both zero, but we can't - // assume that c²+d² != 0 follows, because for tiny values of c - // and/or d c²+d² can underflow to zero. Check that c²+d² is - // nonzero,return if it's not. - if cc_plus_dd.CmpFloat64(0) == 0 { - return false - } - - ac.Set(&v.Real) - - ac.Mul(&rv.Real) // ac - - bd.Set(&v.Imag) - - bd.Mul(&rv.Imag) // bd - - bc.Set(&v.Imag) - - bc.Mul(&rv.Real) // bc - - ad.Set(&v.Real) - - ad.Mul(&rv.Imag) // ad - - v.Real.Set(&ac) - - v.Real.Add(&bd) // ac+bd - v.Real.Quo(&cc_plus_dd) // (ac+bd)/(cc+dd) - - v.Imag.Set(&bc) - - v.Imag.Sub(&ad) // bc-ad - v.Imag.Quo(&cc_plus_dd) // (bc+ad)/(cc+dd) - - return true -} - // Is n a Go language constant (as opposed to a compile-time constant)? // Expressions derived from nil, like string([]byte(nil)), while they // may be known at compile time, are not Go language constants. diff --git a/src/cmd/compile/internal/gc/mpfloat.go b/src/cmd/compile/internal/gc/mpfloat.go index 8d7036ba19..5977ef9748 100644 --- a/src/cmd/compile/internal/gc/mpfloat.go +++ b/src/cmd/compile/internal/gc/mpfloat.go @@ -263,3 +263,74 @@ func fconv(fvp *Mpflt, flag FmtFlag) string { return fmt.Sprintf("%s%.6ge%+d", sign, m, e) } + +// complex multiply v *= rv +// (a, b) * (c, d) = (a*c - b*d, b*c + a*d) +func (v *Mpcplx) Mul(rv *Mpcplx) { + var ac, ad, bc, bd Mpflt + + ac.Set(&v.Real) + ac.Mul(&rv.Real) // ac + + bd.Set(&v.Imag) + bd.Mul(&rv.Imag) // bd + + bc.Set(&v.Imag) + bc.Mul(&rv.Real) // bc + + ad.Set(&v.Real) + ad.Mul(&rv.Imag) // ad + + v.Real.Set(&ac) + v.Real.Sub(&bd) // ac-bd + + v.Imag.Set(&bc) + v.Imag.Add(&ad) // bc+ad +} + +// complex divide v /= rv +// (a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d) +func (v *Mpcplx) Div(rv *Mpcplx) bool { + if rv.Real.CmpFloat64(0) == 0 && rv.Imag.CmpFloat64(0) == 0 { + return false + } + + var ac, ad, bc, bd, cc_plus_dd Mpflt + + cc_plus_dd.Set(&rv.Real) + cc_plus_dd.Mul(&rv.Real) // cc + + ac.Set(&rv.Imag) + ac.Mul(&rv.Imag) // dd + cc_plus_dd.Add(&ac) // cc+dd + + // We already checked that c and d are not both zero, but we can't + // assume that c²+d² != 0 follows, because for tiny values of c + // and/or d c²+d² can underflow to zero. Check that c²+d² is + // nonzero, return if it's not. + if cc_plus_dd.CmpFloat64(0) == 0 { + return false + } + + ac.Set(&v.Real) + ac.Mul(&rv.Real) // ac + + bd.Set(&v.Imag) + bd.Mul(&rv.Imag) // bd + + bc.Set(&v.Imag) + bc.Mul(&rv.Real) // bc + + ad.Set(&v.Real) + ad.Mul(&rv.Imag) // ad + + v.Real.Set(&ac) + v.Real.Add(&bd) // ac+bd + v.Real.Quo(&cc_plus_dd) // (ac+bd)/(cc+dd) + + v.Imag.Set(&bc) + v.Imag.Sub(&ad) // bc-ad + v.Imag.Quo(&cc_plus_dd) // (bc+ad)/(cc+dd) + + return true +} -- 2.50.0