mirror of
https://github.com/golang/go
synced 2024-11-22 01:54:42 -07:00
complex constant multiply and divide
R=rsc CC=golang-dev https://golang.org/cl/217041
This commit is contained in:
parent
d17ffb9753
commit
fc010adcd7
@ -9,6 +9,7 @@ char *runtimeimport =
|
|||||||
"func \"\".printfloat (? float64)\n"
|
"func \"\".printfloat (? float64)\n"
|
||||||
"func \"\".printint (? int64)\n"
|
"func \"\".printint (? int64)\n"
|
||||||
"func \"\".printuint (? uint64)\n"
|
"func \"\".printuint (? uint64)\n"
|
||||||
|
"func \"\".printcomplex (? complex128)\n"
|
||||||
"func \"\".printstring (? string)\n"
|
"func \"\".printstring (? string)\n"
|
||||||
"func \"\".printpointer (? any)\n"
|
"func \"\".printpointer (? any)\n"
|
||||||
"func \"\".printiface (? any)\n"
|
"func \"\".printiface (? any)\n"
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
#include "go.h"
|
#include "go.h"
|
||||||
#define TUP(x,y) (((x)<<16)|(y))
|
#define TUP(x,y) (((x)<<16)|(y))
|
||||||
|
|
||||||
static Val tocplx(Val);
|
static Val tocplx(Val);
|
||||||
static Val toflt(Val);
|
static Val toflt(Val);
|
||||||
static Val tostr(Val);
|
static Val tostr(Val);
|
||||||
static Val copyval(Val);
|
static Val copyval(Val);
|
||||||
|
static void cmplxmpy(Mpcplx *v, Mpcplx *rv);
|
||||||
|
static void cmplxdiv(Mpcplx *v, Mpcplx *rv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* truncate float literal fv to 32-bit or 64-bit precision
|
* truncate float literal fv to 32-bit or 64-bit precision
|
||||||
@ -614,9 +616,10 @@ evconst(Node *n)
|
|||||||
mpsubfltflt(&v.u.cval->imag, &rv.u.cval->imag);
|
mpsubfltflt(&v.u.cval->imag, &rv.u.cval->imag);
|
||||||
break;
|
break;
|
||||||
case TUP(OMUL, CTCPLX):
|
case TUP(OMUL, CTCPLX):
|
||||||
goto illegal; // TODO
|
cmplxmpy(v.u.cval, rv.u.cval);
|
||||||
|
break;
|
||||||
case TUP(ODIV, CTCPLX):
|
case TUP(ODIV, CTCPLX):
|
||||||
goto illegal; // TODO
|
cmplxdiv(v.u.cval, rv.u.cval);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUP(OEQ, CTNIL):
|
case TUP(OEQ, CTNIL):
|
||||||
@ -793,6 +796,13 @@ unary:
|
|||||||
mpnegflt(v.u.fval);
|
mpnegflt(v.u.fval);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TUP(OPLUS, CTCPLX):
|
||||||
|
break;
|
||||||
|
case TUP(OMINUS, CTCPLX):
|
||||||
|
mpnegflt(&v.u.cval->real);
|
||||||
|
mpnegflt(&v.u.cval->imag);
|
||||||
|
break;
|
||||||
|
|
||||||
case TUP(ONOT, CTBOOL):
|
case TUP(ONOT, CTBOOL):
|
||||||
if(!v.u.bval)
|
if(!v.u.bval)
|
||||||
goto settrue;
|
goto settrue;
|
||||||
@ -1187,3 +1197,65 @@ convconst(Node *con, Type *t, Val *val)
|
|||||||
fatal("convconst %lT constant", t);
|
fatal("convconst %lT constant", t);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// complex multiply v *= rv
|
||||||
|
// (a, b) * (c, d) = (a*c - b*d, b*c + a*d)
|
||||||
|
static void
|
||||||
|
cmplxmpy(Mpcplx *v, Mpcplx *rv)
|
||||||
|
{
|
||||||
|
Mpflt ac, bd, bc, ad;
|
||||||
|
|
||||||
|
mpmovefltflt(&ac, &v->real);
|
||||||
|
mpmulfltflt(&ac, &rv->real); // ac
|
||||||
|
|
||||||
|
mpmovefltflt(&bd, &v->imag);
|
||||||
|
mpmulfltflt(&bd, &rv->imag); // bd
|
||||||
|
|
||||||
|
mpmovefltflt(&bc, &v->imag);
|
||||||
|
mpmulfltflt(&bc, &rv->real); // bc
|
||||||
|
|
||||||
|
mpmovefltflt(&ad, &v->real);
|
||||||
|
mpmulfltflt(&ad, &rv->imag); // ad
|
||||||
|
|
||||||
|
mpmovefltflt(&v->real, &ac);
|
||||||
|
mpsubfltflt(&v->real, &bd); // ac-bd
|
||||||
|
|
||||||
|
mpmovefltflt(&v->imag, &bc);
|
||||||
|
mpaddfltflt(&v->imag, &ad); // bc+ad
|
||||||
|
}
|
||||||
|
|
||||||
|
// complex divide v /= rv
|
||||||
|
// (a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d)
|
||||||
|
static void
|
||||||
|
cmplxdiv(Mpcplx *v, Mpcplx *rv)
|
||||||
|
{
|
||||||
|
Mpflt ac, bd, bc, ad, cc_plus_dd;
|
||||||
|
|
||||||
|
mpmovefltflt(&cc_plus_dd, &rv->real);
|
||||||
|
mpmulfltflt(&cc_plus_dd, &rv->real); // cc
|
||||||
|
|
||||||
|
mpmovefltflt(&ac, &rv->imag);
|
||||||
|
mpmulfltflt(&ac, &rv->imag); // dd
|
||||||
|
|
||||||
|
mpaddfltflt(&cc_plus_dd, &ac); // cc+dd
|
||||||
|
|
||||||
|
mpmovefltflt(&ac, &v->real);
|
||||||
|
mpmulfltflt(&ac, &rv->real); // ac
|
||||||
|
|
||||||
|
mpmovefltflt(&bd, &v->imag);
|
||||||
|
mpmulfltflt(&bd, &rv->imag); // bd
|
||||||
|
|
||||||
|
mpmovefltflt(&bc, &v->imag);
|
||||||
|
mpmulfltflt(&bc, &rv->real); // bc
|
||||||
|
|
||||||
|
mpmovefltflt(&ad, &v->real);
|
||||||
|
mpmulfltflt(&ad, &rv->imag); // ad
|
||||||
|
|
||||||
|
mpmovefltflt(&v->real, &ac);
|
||||||
|
mpaddfltflt(&v->real, &bd); // ac+bd
|
||||||
|
mpdivfltflt(&v->real, &cc_plus_dd); // (ac+bd)/(cc+dd)
|
||||||
|
|
||||||
|
mpmovefltflt(&v->imag, &bc);
|
||||||
|
mpsubfltflt(&v->imag, &ad); // bc-ad
|
||||||
|
mpdivfltflt(&v->imag, &cc_plus_dd); // (bc+ad)/(cc+dd)
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ func printbool(bool)
|
|||||||
func printfloat(float64)
|
func printfloat(float64)
|
||||||
func printint(int64)
|
func printint(int64)
|
||||||
func printuint(uint64)
|
func printuint(uint64)
|
||||||
|
func printcomplex(complex128)
|
||||||
func printstring(string)
|
func printstring(string)
|
||||||
func printpointer(any)
|
func printpointer(any)
|
||||||
func printiface(any)
|
func printiface(any)
|
||||||
|
@ -1370,6 +1370,10 @@ checkconv(Type *nt, Type *t, int explicit, int *op, int *et, char *desc)
|
|||||||
if(isint[nt->etype] || isfloat[nt->etype])
|
if(isint[nt->etype] || isfloat[nt->etype])
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
// between versions of complex
|
||||||
|
if(iscomplex[t->etype] || iscomplex[nt->etype])
|
||||||
|
return 1;
|
||||||
|
|
||||||
// to string
|
// to string
|
||||||
if(istype(t, TSTRING)) {
|
if(istype(t, TSTRING)) {
|
||||||
// integer rune
|
// integer rune
|
||||||
|
@ -794,11 +794,13 @@ walkexpr(Node **np, NodeList **init)
|
|||||||
case OCONV:
|
case OCONV:
|
||||||
case OCONVNOP:
|
case OCONVNOP:
|
||||||
if(thechar == '5') {
|
if(thechar == '5') {
|
||||||
if(isfloat[n->left->type->etype] && (n->type->etype == TINT64 || n->type->etype == TUINT64)) {
|
if(isfloat[n->left->type->etype] &&
|
||||||
|
(n->type->etype == TINT64 || n->type->etype == TUINT64)) {
|
||||||
n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
|
n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
if((n->left->type->etype == TINT64 || n->left->type->etype == TUINT64) && isfloat[n->type->etype]) {
|
if((n->left->type->etype == TINT64 || n->left->type->etype == TUINT64) &&
|
||||||
|
isfloat[n->type->etype]) {
|
||||||
n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64]));
|
n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64]));
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
@ -1727,7 +1729,7 @@ walkprint(Node *nn, NodeList **init, int defer)
|
|||||||
} else if(iscomplex[et]) {
|
} else if(iscomplex[et]) {
|
||||||
if(defer) {
|
if(defer) {
|
||||||
fmtprint(&fmt, "%%f");
|
fmtprint(&fmt, "%%f");
|
||||||
t = types[TFLOAT64];
|
t = types[TCOMPLEX128];
|
||||||
} else
|
} else
|
||||||
on = syslook("printcomplex", 0);
|
on = syslook("printcomplex", 0);
|
||||||
} else if(et == TBOOL) {
|
} else if(et == TBOOL) {
|
||||||
@ -2036,8 +2038,10 @@ convas(Node *n, NodeList **init)
|
|||||||
if(lt == T || rt == T)
|
if(lt == T || rt == T)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if(isblank(n->left))
|
if(isblank(n->left)) {
|
||||||
|
defaultlit(&n->right, T);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if(n->left->op == OINDEXMAP) {
|
if(n->left->op == OINDEXMAP) {
|
||||||
n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init,
|
n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init,
|
||||||
|
Loading…
Reference in New Issue
Block a user