goto bad;
                        case CTFLT:
                        case CTINT:
-                               if(explicit)
-                                       goto bad;
                                n->val = tocplx(n->val);
                                break;
                        case CTCPLX:
                f = mal(sizeof(*f));
                mpmovefltflt(f, &v.u.cval->real);
                if(mpcmpfltc(&v.u.cval->imag, 0) != 0)
-                       yyerror("constant %#F truncated to real", v.u.fval);
+                       yyerror("constant %#F%+#Fi truncated to real", &v.u.cval->real, &v.u.cval->imag);
                v.ctype = CTFLT;
                v.u.fval = f;
                break;
        case CTCPLX:
                i = mal(sizeof(*i));
                if(mpmovefltfix(i, &v.u.cval->real) < 0)
-                       yyerror("constant %#F truncated to integer", v.u.fval);
+                       yyerror("constant %#F%+#Fi truncated to integer", &v.u.cval->real, &v.u.cval->imag);
                if(mpcmpfltc(&v.u.cval->imag, 0) != 0)
-                       yyerror("constant %#F truncated to real", v.u.fval);
+                       yyerror("constant %#F%+#Fi truncated to real", &v.u.cval->real, &v.u.cval->imag);
                v.ctype = CTINT;
                v.u.xval = i;
                break;
 
                // for well in range, convert to double and use print's %g
                if(-900 < fvp->exp && fvp->exp < 900) {
                        d = mpgetflt(fvp);
+                       if(d >= 0 && (fp->flags & FmtSign))
+                               fmtprint(fp, "+");
                        return fmtprint(fp, "%g", d);
                }
                // TODO(rsc): for well out of range, print
 
        c64 = cmplx(f32, f32)
        c128 = cmplx(f64, f64)
 
+       _ = complex(0) // ok
        _ = cmplx(f, f32)       // ERROR "cmplx"
        _ = cmplx(f, f64)       // ERROR "cmplx"
        _ = cmplx(f32, f)       // ERROR "cmplx"