灯下 登录
计算机科学 / SICP / subsection 中英对照

2.4.1 Representations for Complex Numbers

We will develop a system that performs arithmetic operations on complex numbers

as a simple but unrealistic example of a program that uses generic operations.

We begin by discussing two plausible representations for complex numbers as

ordered pairs: rectangular form (real part and imaginary part) and polar form

(magnitude and angle).

Section 2.4.2 will show how both representations can be made to coexist in a

single system through the use of type tags and generic operations.

我们将开发一个对复数执行算术运算的系统,以此作为一个使用通用操作的程序的简单(但不切实际)示例。首先讨论将复数表示为有序序对的两种合理方案:直角坐标形式(实部与虚部)和极坐标形式(模与辐角)。2.4.2 节将说明如何借助类型标签和通用操作,使两种表示在同一个系统中共存。

Like rational numbers, complex numbers are naturally represented as ordered

pairs. The set of complex numbers can be thought of as a two-dimensional space

with two orthogonal axes, the “real” axis and the “imaginary” axis. (See

Figure 2.20.) From this point of view, the complex number

z

=

x

+

i

y (where i

与有理数类似,复数天然地以有序序对来表示。复数集合可以看作一个二维空间,具有两条互相垂直的坐标轴——“实”轴与“虚”轴(见图 2.20)。从这一视角看,复数 z = x + iy(其中 i

2

=

−1) can be thought of as the point in the plane

whose real coordinate is x and whose imaginary coordinate is y.

Addition of complex numbers reduces in this representation to addition of

coordinates:

Real-part

(

= −1)可以看作平面上实坐标为 x、虚坐标为 y 的点。在这种表示下,复数的加法化归为坐标的加法:

Real-part (

z
1

+

z
2

)

=

Real-part
(
Real-part (

z
1

)
+

Real-part
(
Real-part (

z
2

)
,

Imaginary-part
(
Imaginary-part (

z
1

+

z
2

)

=

Imaginary-part
(
Imaginary-part (

z
1

)
+

Imaginary-part
(
Imaginary-part (

z
2

)

.

Figure 2.20: Complex numbers as points in the plane.

)

.

图 2.20:平面上的复数点。

When multiplying complex numbers, it is more natural to think in terms of

representing a complex number in polar form, as a magnitude and an angle (r

and A in Figure 2.20). The product of two complex numbers is the

vector obtained by stretching one complex number by the length of the other and

then rotating it through the angle of the other:

Magnitude

(

在进行复数乘法时,用极坐标形式表示复数更为自然——即用模和辐角表示(图 2.20 中的 r 和 A)。两个复数的乘积是这样一个向量:将其中一个复数按另一个复数的模拉伸,再旋转另一个复数的辐角所得到:

Magnitude (

z
1

z
2

)

=

Magnitude
(

z
1

)

Magnitude
(

z
2

)
,

Angle
(

z
1

z
2

)

=

Angle
(

z
1

)
+
Angle
(

z
2

)
.

Thus, there are two different representations for complex numbers, which are

appropriate for different operations. Yet, from the viewpoint of someone

writing a program that uses complex numbers, the principle of data abstraction

suggests that all the operations for manipulating complex numbers should be

available regardless of which representation is used by the computer. For

example, it is often useful to be able to find the magnitude of a complex

number that is specified by rectangular coordinates. Similarly, it is often

useful to be able to determine the real part of a complex number that is

specified by polar coordinates.

由此,复数有两种不同的表示方式,各自适用于不同的运算。然而,从编写使用复数程序的人的角度来看,数据抽象原则要求:无论计算机内部采用哪种表示方式,所有操作复数的运算都应当可以使用。例如,当一个复数以直角坐标形式给出时,能够求出它的模 (magnitude) 往往很有用;同样,当一个复数以极坐标形式给出时,能够求出它的实部也常常是必要的。

To design such a system, we can follow the same data-abstraction strategy we

followed in designing the rational-number package in 2.1.1.

Assume that the operations on complex numbers are implemented in terms of four

selectors: real-part, imag-part, magnitude, and

angle. Also assume that we have two procedures for constructing complex

numbers: make-from-real-imag returns a complex number with specified

real and imaginary parts, and make-from-mag-ang returns a complex number

with specified magnitude and angle. These procedures have the property that,

for any complex number z, both

为了设计这样一个系统,我们可以沿用 2.1.1 节设计有理数程序包时所采取的数据抽象策略。假设对复数的操作是通过四个选择函数来实现的:real-part、imag-part、magnitude 和 angle。同时假设我们有两个用于构造复数的过程:make-from-real-imag 返回一个具有指定实部和虚部的复数,make-from-mag-ang 返回一个具有指定模和辐角的复数。这些过程具有如下性质:对任意复数 z,以下两式

and

以及

produce complex numbers that are equal to z.

都能产生与 z 相等的复数。

Using these constructors and selectors, we can implement arithmetic on complex

numbers using the “abstract data” specified by the constructors and

selectors, just as we did for rational numbers in 2.1.1. As

shown in the formulas above, we can add and subtract complex numbers in terms

of real and imaginary parts while multiplying and dividing complex numbers in

terms of magnitudes and angles:

利用这些构造函数和选择函数,我们可以依据构造函数与选择函数所规定的"抽象数据"来实现复数的算术运算,正如我们在 2.1.1 节对有理数所做的那样。如上面的公式所示,复数的加法和减法可以用实部和虚部来表达,而复数的乘法和除法则用模和辐角来表达:

To complete the complex-number package, we must choose a representation and we

must implement the constructors and selectors in terms of primitive numbers and

primitive list structure. There are two obvious ways to do this: We can

represent a complex number in “rectangular form” as a pair (real part,

imaginary part) or in “polar form” as a pair (magnitude, angle). Which shall

we choose?

为了完成复数程序包,我们必须选择一种表示方式,并用基本数和基本表结构来实现构造函数和选择函数。显然有两种方法可以做到这一点:我们可以将复数表示为"直角形式"——一个序对(实部,虚部),或表示为"极坐标形式"——一个序对(模,辐角)。我们应当选哪种?

In order to make the different choices concrete, imagine that there are two

programmers, Ben Bitdiddle and Alyssa P. Hacker, who are independently

designing representations for the complex-number system. Ben chooses to

represent complex numbers in rectangular form. With this choice, selecting the

real and imaginary parts of a complex number is straightforward, as is

constructing a complex number with given real and imaginary parts. To find the

magnitude and the angle, or to construct a complex number with a given

magnitude and angle, he uses the trigonometric relations

为了使不同的选择更加具体,设想有两位程序员——Ben Bitdiddle 和 Alyssa P. Hacker——正在各自独立地为复数系统设计表示方式。Ben 选择用直角形式表示复数。有了这个选择,从复数中取出实部和虚部是直截了当的,用给定的实部和虚部构造复数也是如此。而要求模和辐角,或者用给定的模和辐角构造复数,他则借助三角关系式

which relate the real and imaginary parts (

x

,

y

) to the magnitude and

the angle (

r

,

A

). Ben’s

representation is therefore given by the following selectors and constructors:

这些关系式将实部和虚部(

x

,

y

)与模和辐角(

r

,

A

)联系起来。因此,Ben 的表示方式由以下选择函数和构造函数给出:

Alyssa, in contrast, chooses to represent complex numbers in polar form. For

her, selecting the magnitude and angle is straightforward, but she has to use

the trigonometric relations to obtain the real and imaginary parts. Alyssa’s

representation is:

Alyssa 则选择用极坐标形式表示复数。对她而言,取出模和辐角是直截了当的,但她必须借助三角关系式来求实部和虚部。Alyssa 的表示方式如下:

The discipline of data abstraction ensures that the same implementation of

add-complex, sub-complex, mul-complex, and

div-complex will work with either Ben’s representation or Alyssa’s

representation.

数据抽象原则保证了 add-complex、sub-complex、mul-complex 和 div-complex 的同一套实现,可以在 Ben 的表示方式或 Alyssa 的表示方式下正常工作。

Racket #lang sicp
(make-from-real-imag (real-part z)
 (imag-part z))
Racket #lang sicp
(make-from-mag-ang (magnitude z)
 (angle z))
Racket #lang sicp
(define (add-complex z1 z2)
 (make-from-real-imag
 (+ (real-part z1) (real-part z2))
 (+ (imag-part z1) (imag-part z2))))

(define (sub-complex z1 z2)
 (make-from-real-imag
 (- (real-part z1) (real-part z2))
 (- (imag-part z1) (imag-part z2))))

(define (mul-complex z1 z2)
 (make-from-mag-ang
 (* (magnitude z1) (magnitude z2))
 (+ (angle z1) (angle z2))))

(define (div-complex z1 z2)
 (make-from-mag-ang
 (/ (magnitude z1) (magnitude z2))
 (- (angle z1) (angle z2))))
Racket #lang sicp
(define (real-part z) (car z))
(define (imag-part z) (cdr z))

(define (magnitude z)
 (sqrt (+ (square (real-part z))
 (square (imag-part z)))))

(define (angle z)
 (atan (imag-part z) (real-part z)))

(define (make-from-real-imag x y)
 (cons x y))

(define (make-from-mag-ang r a)
 (cons (* r (cos a)) (* r (sin a))))
Racket #lang sicp
(define (real-part z)
 (* (magnitude z) (cos (angle z))))

(define (imag-part z)
 (* (magnitude z) (sin (angle z))))

(define (magnitude z) (car z))
(define (angle z) (cdr z))

(define (make-from-real-imag x y)
 (cons (sqrt (+ (square x) (square y)))
 (atan y x)))

(define (make-from-mag-ang r a)
 (cons r a))