1

I've come a long way in the past two weeks since asking my first question, having written a tictactoe game using grid layout and button-pushes to make x and o and declare winner and a class that performs complex number arithmetic (e.g., z1=-3-4i plus z2=7+i via cAdd(z1,z2)) and calculations (e.g., sin(z1) and log(z2)) correctly. (Confirmed by and implemented via help from a CAS called Derive.)

No problem so far.

So I decided to enhance cAdd to accept more than two complex numbers (e.g, cAdd(z1,z2,z3)) and found the following syntax for varying-length argument lists:

public ComplexNumber cAdd ( ComplexNumber ... a);

But whereas the two-parameter version of cAdd(z1,z2) works fine, the "varargs" version (e.g., cAdd(z1,z2,z3)) gives correct results BUT CHANGES THE PARAMETER VALUES so that if z1 is used in a later calculation, it's not what it started out as.

Here's code, followed by output.

  class ComplexNumber {

    double real, imag;

    public ComplexNumber() {                // default constructor
    }

    public ComplexNumber(double a, double b) {    // initializer constructor
        real = a;
        imag = b;
    }

  public class CBug {

    public static void cPrint(String s, ComplexNumber z) {
        System.out.println(s + z.real + " + " + z.imag + "i");
    }

    public static void dump(int n, ComplexNumber z, ComplexNumber [] a){
        System.out.print("Dump " + n + "; sum so far is " );
        cPrint("z = ", z);
        for (int i = 0; i < a.length; i++)
            cPrint("" + i + ": " ,a[i]);
        System.out.println("");
    }

    public static ComplexNumber cAdd(ComplexNumber ... a) {
        ComplexNumber z = a[0];
        for (int i = 1; i < a.length; i++){
            dump(i,z,a);
            z.real = z.real + a[i].real;
            z.imag = z.imag + a[i].imag;
        }
        dump(99,z,a);
        return z;
    }

    public static void main(String[] args) {
        ComplexNumber sum = new ComplexNumber();
        ComplexNumber z1 = new ComplexNumber(1000,500);
        ComplexNumber z2 = new ComplexNumber(7, 1);
        ComplexNumber z3 = new ComplexNumber(100,100);
        cPrint("z1 = ", z1);
        cPrint("z2 = ", z2);
        cPrint("z3 = ", z3);

        System.out.println("");

        System.out.println("++++++++++++++++++++++");
        sum = cAdd(z1,    z2,    z3) ;
        cPrint     ("z1 + z2 + z3 = " , sum);
        System.out.println("--------------------");

        cPrint("z1 = ", z1);
        cPrint("z2 = ", z2);
        cPrint("z3 = ", z3);
    }
  }

Output:

run:
z1 = 1000.0 + 500.0i
z2 = 7.0 + 1.0i
z3 = 100.0 + 100.0i

++++++++++++++++++++++
Dump 1; sum so far is z = 1000.0 + 500.0i   [correct]
0: 1000.0 + 500.0i
1: 7.0 + 1.0i
2: 100.0 + 100.0i

Dump 2; sum so far is z = 1007.0 + 501.0i     [correct]
0: 1007.0 + 501.0i        [but WHY DID ARG[0] CHANGE to "z so far"?]
1: 7.0 + 1.0i
2: 100.0 + 100.0i

Dump 99; sum so far is z = 1107.0 + 601.0i   [correct]
0: 1107.0 + 601.0i         [WHY DID ARG[0] CHANGE AGAIN to new "z so far"?]
1: 7.0 + 1.0i
2: 100.0 + 100.0i

z1 + z2 + z3 = 1107.0 + 601.0i                [correct]
--------------------
z1 = 1107.0 + 601.0i          [WHY DID z1 (a.k.a. arg[0]) CHANGE?]
z2 = 7.0 + 1.0i
z3 = 100.0 + 100.0i
BUILD SUCCESSFUL (total time: 0 seconds)

Can't use 1st parameter in subsequent calculations since cAdd damaged it.

=============================

Here's what I now have for cAdd (since my original "fix" [described in comments below] was a bit wacko]:

 public static ComplexNumber cAdd(ComplexNumber ... a) {
    ComplexNumber z = new ComplexNumber();
    for (int i = 0; i < a.length; i++){
      z.real += a[i].real;
      z.imag += a[i].imag;
    }
    return z;
  }

===============================

4

1 回答 1

2

当您在 中创建变量zcAdd,您将其引用到a[0]. 现在两者都z引用a[0]同一个对象。然后你改变它。

您应该做的是为 的第一个元素制作副本z,这样当您修改 时z,您就不会修改a[0]。像这样的东西:

ComplexNumber z = new ComplexNumber(a[0].real, a[0].imag);
于 2013-09-20T22:18:24.017 回答