Complex.st
changeset 7355 96f466eeddf5
parent 7221 b38093d749b3
child 7377 b2f13d3b9f58
--- a/Complex.st	Fri Jun 13 20:52:21 2003 +0200
+++ b/Complex.st	Mon Jun 16 11:14:59 2003 +0200
@@ -22,7 +22,7 @@
 
 ArithmeticValue subclass:#Complex
 	instanceVariableNames:'real imaginary'
-	classVariableNames:''
+	classVariableNames:'ComplexOne ComplexZero'
 	poolDictionaries:''
 	category:'Magnitude-Numbers'
 !
@@ -53,23 +53,26 @@
 
 documentation
 "
- This is an implementation of complex numbers.  A complex number has real and
- imaginary parts which must be manipulated simultaneously in any numeric processing.
- Complex numbers can be used in many of the same places that regular numbers
- can be used with one major exception of comparisons, since complex numbers cannot
- be directly compared for size (except through lengths of vectors (see absolute
- value)).
+    This class implements complex numbers.  
+    A complex number has real and imaginary parts which must be manipulated simultaneously 
+    in any numeric processing.
+    Complex numbers can be used in many of the same places that regular numbers
+    can be used with one major exception of comparisons, since complex numbers cannot
+    be directly compared for size 
+    (except through lengths of vectors (see absolute value)).
 
-Instance variables:
-    real        <Number> the part of the number which can be expressed as a Real number
-    imaginary   <Number> the part of the number which, in terms of how the number behaves,
-			 has been multiplied by 'i' (-1 sqrt)
+    [Instance variables:]
+       real        <Number> the part of the number which can be expressed as a Real number
+       imaginary   <Number> the part of the number which, in terms of how the number behaves,
+                            has been multiplied by 'i' (-1 sqrt)
 
-Author: Kurt Hebel (hebel@uinova.cerl.uiuc.edu)
+    [Author:]
+        Kurt Hebel (hebel@uinova.cerl.uiuc.edu)
+        minor changes and double dispatching code by cg.
 "
 !
 
-example
+examples
 "
     (5 % 7) real
     (5 % 7) imaginary
@@ -84,43 +87,67 @@
     (1 % 0) * (2 % 0)   
     (1 % 0) * (0 % 2)   
     (1 % 0) * (2 % 3)
+
+    (1 % 2) + 2
+    (1 % 2) * 2
+    2 + (1 % 2) 
+    2 * (1 % 2) 
+
 "
 ! !
 
 !Complex class methodsFor:'instance creation'!
 
 fromReal: aNumber
-	"Create a new complex number from the given real number."
-	^ self basicNew setReal: aNumber setImaginary: 0
+    "Create a new complex number from the given real number."
+
+    ^ self basicNew setReal: aNumber setImaginary: 0
+!
+
+imaginary: v
+    "Create a new complex number with 0 as real and given imaginary parts.
+     If the imaginary part is zero, return the real part of the number."
+
+    v = 0 ifTrue: [^ 0].
+    ^ self basicNew setReal: 0 setImaginary: v
+!
+
+real: aNumber
+    "Create a new complex number from the given real number."
+
+    ^ self basicNew setReal: aNumber setImaginary: 0
 !
 
 real: u imaginary: v
-	"Create a new complex number with the given real and imaginary parts.  If the
-	 imaginary part is zero, return the real part of the number."
-	^v = 0 ifTrue: [u]
-	       ifFalse: [self basicNew setReal: u setImaginary: v]
+    "Create a new complex number with the given real and imaginary parts.  If the
+     imaginary part is zero, return the real part of the number."
+
+    v = 0 ifTrue: [^ u].
+    ^ self basicNew setReal: u setImaginary: v
 ! !
 
 !Complex class methodsFor:'constants access'!
 
 unity
-	"Answer the value which allows, for any given arithmetic value, the following to be true
-
-	 aNumber * aNumber class unity = aNumber
+    "Answer the value which allows, for any given arithmetic value, the following to be true:
+        aNumber * aNumber class unity = aNumber
+     This must be true regardless of how a given subclass chooses to define #*"
 
-	This must be true regardless of how a given subclass chooses to define #*"
-
-	^self fromReal: 1
+    ComplexOne isNil ifTrue:[
+        ComplexOne := self fromReal: 1
+    ].
+    ^ ComplexOne
 !
 
 zero
-	"Answer the value which allows, for any given arithmetic value, the following to be true
-
-		aNumber + aNumber class zero = aNumber
+    "Answer the value which allows, for any given arithmetic value, the following to be true:
+        aNumber + aNumber class zero = aNumber
+     This must be true regardless of how a given subclass chooses to define #+"
 
-	This must be true regardless of how a given subclass chooses to define #+"
-
-	^self fromReal: 0
+    ComplexZero isNil ifTrue:[
+        ComplexZero := self fromReal: 0
+    ].
+    ^ ComplexZero
 ! !
 
 !Complex class methodsFor:'exception handling'!
@@ -144,311 +171,554 @@
 !Complex methodsFor:'accessing'!
 
 imaginary
-	"Return the imaginary part of the complex number."
-	^ imaginary
+    "Return the imaginary part of the complex number."
+
+    ^ imaginary
+!
+
+imaginaryPart
+    "Return the imaginary part of the complex number.
+     An alias for imaginary (for compatibility with other complex implementations)"
+
+    ^ imaginary
 !
 
 real
-	"Return the real part of the complex number."
-	^ real
+    "Return the real part of the complex number."
+
+    ^ real
+!
+
+realPart
+    "Return the real part of the complex number.
+     An alias for real (for compatibility with other complex implementations)"
+
+    ^ real
 ! !
 
 !Complex methodsFor:'arithmetic'!
 
 * aNumber 
-	"Return the product of the receiver and the argument."
-
-	| u v r i |
+    "Return the product of the receiver and the argument."
 
-	aNumber isComplex ifTrue:[
-	    u := aNumber real.
-	    v := aNumber imaginary.
-	    r := (real * u) - (imaginary * v).
-	    i  := (real * v) + (imaginary * u).
-	    i = 0 ifTrue:[ ^ r ].
-	    ^ Complex real:r imaginary:i
-	].
-	^ self retry: #* coercing: aNumber
+"/    | u v r i |
+"/
+"/    aNumber isComplex ifTrue:[
+"/        u := aNumber real.
+"/        v := aNumber imaginary.
+"/        r := (real * u) - (imaginary * v).
+"/        i  := (real * v) + (imaginary * u).
+"/        i = 0 ifTrue:[ ^ r ].
+"/        ^ Complex real:r imaginary:i
+"/    ].
+    ^ aNumber productFromComplex:self. 
 
     "Modified: / 8.7.1998 / 12:12:37 / cg"
 !
 
 + aNumber 
-	"Return the sum of the receiver and the argument."
-
-	| r i |
+    "Return the sum of the receiver and the argument."
 
-	aNumber isComplex ifTrue: [
-	    r := aNumber real + real.
-	    i := aNumber imaginary + imaginary.
-	    i = 0 ifTrue:[ ^ r ].
-	    ^ Complex real:r imaginary:i
-	].
-	^ self retry: #+ coercing: aNumber
+"/    | r i |
+"/
+"/    aNumber isComplex ifTrue: [
+"/        r := aNumber real + real.
+"/        i := aNumber imaginary + imaginary.
+"/        i = 0 ifTrue:[ ^ r ].
+"/        ^ Complex real:r imaginary:i
+"/    ].
+    ^ aNumber sumFromComplex:self. 
 
     "Modified: / 8.7.1998 / 12:15:42 / cg"
 !
 
 - aNumber
-	"Return the difference of the receiver and the argument."
-
-	| r i |
+    "Return the difference of the receiver and the argument."
 
-	aNumber isComplex ifTrue: [
-	    r := real - aNumber real.
-	    i := imaginary - aNumber imaginary.
-	    i = 0 ifTrue:[ ^ r ].
-	    ^ Complex real:r imaginary:i.
-	].
-	^ self retry: #- coercing: aNumber
+"/    | r i |
+"/
+"/    aNumber isComplex ifTrue: [
+"/        r := real - aNumber real.
+"/        i := imaginary - aNumber imaginary.
+"/        i = 0 ifTrue:[ ^ r ].
+"/        ^ Complex real:r imaginary:i.
+"/    ].
+    ^ aNumber differenceFromComplex:self. 
 
     "Modified: / 8.7.1998 / 12:15:38 / cg"
 !
 
 / aNumber 
-	"Return the quotient of the receiver and the argument."
-
-	| denom u v r i |
+    "Return the quotient of the receiver and the argument."
 
-	aNumber isComplex ifTrue:[ 
-	    u := aNumber real.
-	    v := aNumber imaginary.
-	    denom := u * u + (v * v).
-	    r := u * real + (v * imaginary) / denom.
-	    i := u * imaginary - (v * real) / denom.
-	    i = 0 ifTrue:[ ^ r ].
-	    ^ Complex real:r imaginary:i
-	].
-	^ self retry: #/ coercing: aNumber
+"/    | denom u v r i |
+"/
+"/    aNumber isComplex ifTrue:[ 
+"/        u := aNumber real.
+"/        v := aNumber imaginary.
+"/        denom := u * u + (v * v).
+"/        r := u * real + (v * imaginary) / denom.
+"/        i := u * imaginary - (v * real) / denom.
+"/        i = 0 ifTrue:[ ^ r ].
+"/        ^ Complex real:r imaginary:i
+"/    ].
+    ^ aNumber quotientFromComplex:self. 
 
     "Modified: / 8.7.1998 / 12:15:34 / cg"
 !
 
 abs
-	"Return the magnitude (or absolute value) of the complex number."
+    "Return the magnitude (or absolute value) of the complex number
+     (thats the distance from the origin in the complex plane)."
 
-	^ (real * real + (imaginary * imaginary)) sqrt
+    ^ (real * real + (imaginary * imaginary)) sqrt
+
+    "
+     (1 % 1) abs
+    "
 !
 
 conjugated
-	"Return the complex conjugate of this complex number."
+    "Return the complex conjugate of this complex number
+     (i.e. with imaginary part negated)."
+
+    ^ Complex 
+        real: real
+        imaginary: imaginary negated
+!
+
+differenceFromComplex:aComplex
+    "Return the difference of the argument, aComplex and the receiver."
+
+    | r i |
+
+    r := aComplex real - real.
+    i := aComplex imaginary - imaginary.
+    i = 0 ifTrue:[ ^ r ].
+    ^ Complex real:r imaginary:i.
+!
+
+modulus
+    | absReal absImag multiplicand quotient |
+
+    absReal := real abs.
+    absImag := imaginary abs.
+
+    absReal >= absImag ifTrue: [ 
+        multiplicand := absReal.  
+        quotient := imaginary / real 
+    ] ifFalse: [ 
+        multiplicand := absImag.  
+        quotient := real / imaginary 
+    ].
+    ^ multiplicand * ((1 + (quotient * quotient)) sqrt)
+!
+
+negated
+    "return a new complex with both real and imaginary parts negated"
+
+    ^ Complex 
+        real: real negated 
+        imaginary: imaginary negated
+!
+
+productFromComplex:aComplex 
+    "Return the product of the receiver and the argument, aComplex."
+
+    | u v r i |
 
-	^ Complex real: real imaginary: imaginary negated
+    u := aComplex real.
+    v := aComplex imaginary.
+    r := (real * u) - (imaginary * v).
+    i  := (real * v) + (imaginary * u).
+    i = 0 ifTrue:[ ^ r ].
+    ^ Complex real:r imaginary:i
+!
+
+quotientFromComplex:aComplex 
+    "Return the quotient of the argument, aComplex and the receiver."
+
+    | denom nr ni r i |
+
+    nr := aComplex real.
+    ni := aComplex imaginary.
+    denom := real * real + (imaginary * imaginary).
+    r := real * nr + (imaginary * ni) / denom.
+    i := real * ni - (imaginary * nr) / denom.
+    i = 0 ifTrue:[ ^ r ].
+    ^ Complex real:r imaginary:i
+
+"/ is the stuff below better ?
+"/    "Implement complex division (a + ib) / (c + id).  
+"/     Due to double dispatch, in this routine
+"/        self = (c + id) and aComplex = (a + ib)."
+"/
+"/    | quotient denominator |
+"/
+"/    self realPart abs >= (self imaginaryPart abs)
+"/        ifTrue: [ 
+"/            quotient := self imaginaryPart / self realPart.
+"/            denominator := self realPart + (self imaginaryPart * quotient).
+"/            ^ Complex 
+"/                real: (aComplex realPart + (aComplex imaginaryPart * quotient)) / denominator
+"/                imaginary: (aComplex imaginaryPart - (aComplex realPart * quotient)) / denominator ]
+"/        ifFalse: [ 
+"/            quotient := self realPart / self imaginaryPart.
+"/            denominator := (self realPart * quotient) + self imaginaryPart.
+"/            ^ Complex 
+"/                real: ((aComplex realPart * quotient) + aComplex imaginaryPart) / denominator
+"/                imaginary: ((aComplex imaginaryPart * quotient) - aComplex realPart) / denominator ]
+!
+
+sumFromComplex:aComplex 
+    "Return the sum of the receiver and the argument, aComplex."
+
+    | r i |
+
+    r := aComplex real + real.
+    i := aComplex imaginary + imaginary.
+    i = 0 ifTrue:[ ^ r ].
+    ^ Complex real:r imaginary:i
 ! !
 
 !Complex methodsFor:'coercing'!
 
 coerce: aNumber
-
-	^aNumber asComplex
+    ^ aNumber asComplex
 !
 
 generality
-
-	^150
+    ^ 150
 ! !
 
 !Complex methodsFor:'comparing'!
 
 < aNumber
-	^Number
-		raise: #unorderedSignal
-		receiver: self
-		selector: #<
-		arg: aNumber
-		errorString: 'Complex numbers are not well ordered'
+    "raises an error - complex numbers are not well ordered"
+
+    ^ Number
+        raise: #unorderedSignal
+        receiver: self
+        selector: #<
+        arg: aNumber
+        errorString: 'Complex numbers are not well ordered'
+
+    "
+     1 < (2 % 2)
+     (2 % 2) < 1
+    "
 !
 
 = aNumber
-	^ (aNumber real = real) and:[aNumber imaginary = imaginary]
+    "return true, if the argument represents the same numeric value
+     as the receiver, false otherwise"
+
+    ^ aNumber equalFromComplex:self    
 !
 
 hash
-	"Hash is implemented because equals is implemented."
+    "Hash is implemented because equals is implemented."
 
-	^ real hash
+    ^ real hash
 ! !
 
 !Complex methodsFor:'converting'!
 
 asComplex
+    "I am a complex - so return the receiver"
 
-	^self
+    ^ self
 !
 
 asFloat
-
-	imaginary = 0 ifTrue: [^real asFloat].
-	^Number
-		raise: #coercionErrorSignal
-		receiver: self
-		selector: #asFloat
-		errorString: 'Can''t coerce an instance of Complex to a Float'
+    imaginary = 0 ifTrue: [^ real asFloat].
+    ^ Number
+            raise: #coercionErrorSignal
+            receiver: self
+            selector: #asFloat
+            errorString: 'Can''t coerce an instance of Complex to a Float'
 !
 
 asInteger
-
-	imaginary = 0 ifTrue: [^real asInteger].
-	^Number
-		raise: #coercionErrorSignal
-		receiver: self
-		selector: #asInteger
-		errorString: 'Can''t coerce an instance of Complex to an Integer'
+    imaginary = 0 ifTrue: [^real asInteger].
+    ^ Number
+        raise: #coercionErrorSignal
+        receiver: self
+        selector: #asInteger
+        errorString: 'Can''t coerce an instance of Complex to an Integer'
 !
 
 asPoint
-	"Return the complex number as a point."
-	^ real @ imaginary
+    "Return the complex number as a point."
+
+    ^ real @ imaginary
 !
 
 reduceGeneralityIfPossible
-	"Answer the receiver transformed to a lower generality, if such a 
-	transformation is possible without losing information. If not, answer 
-	the receiver"
+    "Answer the receiver transformed to a lower generality, if such a 
+     transformation is possible without losing information. 
+     If not, answer the receiver"
 
-	imaginary isZero
-		ifTrue: [^real]
-		ifFalse: [^self]
+    imaginary isZero
+        ifTrue: [^ real]
+        ifFalse: [^ self]
 ! !
 
 !Complex methodsFor:'double dispatching'!
 
-differenceFromFloat: argument
-	^ argument asComplex - self
-!
+differenceFromFloat:aFloat
+    "Return the difference of the argument, aFloat and the receiver."
+
+    "/ ^ aFloat asComplex - self
+
+    | r |
 
-differenceFromFraction: argument
-	^ argument asComplex - self
+    r := aFloat - real.
+    imaginary = 0 ifTrue:[ ^ r ].
+    ^ Complex real:r imaginary:imaginary
+
+    "
+     (1 % 1) - 1.0 
+     1.0 - (1 % 1) 
+    "
 !
 
-differenceFromInteger: argument
-	^ argument asComplex - self
+differenceFromFraction: aFraction
+    ^ aFraction asComplex - self
+!
+
+differenceFromInteger: anInteger
+    ^ anInteger asComplex - self
 !
 
-productFromFloat: argument
-	^ argument asComplex * self
+equalFromComplex:aComplex
+    ^ (aComplex real = real) and:[aComplex imaginary = imaginary]
 !
 
-productFromFraction: argument
-	^ argument asComplex * self
+equalFromFloat:aFloat
+    imaginary = 0 ifFalse:[^ false].
+    ^ real = aFloat
 !
 
-productFromInteger: argument
-	^ argument asComplex * self
+productFromFloat: aFloat
+    "Return the product of the receiver and the argument, aFloat."
+
+    "/  ^ aFloat asComplex * self
+
+    | u r i |
+
+    u := aFloat.
+    r := (real * aFloat).
+    i  := (imaginary * aFloat).
+    i = 0 ifTrue:[ ^ r ].
+    ^ Complex real:r imaginary:i
+
+    "
+     (1 % 1) * 2.0 
+     (1 % 1) * 0.0 
+     2.0 * (1 % 1)
+    "
 !
 
-quotientFromFloat: argument
-	^ argument asComplex / self
+productFromFraction: aFraction
+    ^ aFraction asComplex * self
 !
 
-quotientFromFraction: argument
-	^ argument asComplex / self
+productFromInteger: anInteger
+    ^ anInteger asComplex * self
+!
+
+quotientFromFloat: aFloat
+    ^ aFloat asComplex / self
 !
 
-quotientFromInteger: argument
-	^ argument asComplex / self
+quotientFromFraction: aFraction
+    ^ aFraction asComplex / self
+!
+
+quotientFromInteger: anInteger
+    ^ anInteger asComplex / self
 !
 
-sumFromFloat: argument
-	^ argument asComplex + self
+sumFromFloat: aFloat
+    "Return the sum of the receiver and the argument, aFloat."
+
+    "/ ^ aFloat asComplex + self
+
+    | r |
+
+    r := aFloat + real.
+    imaginary = 0 ifTrue:[ ^ r ].
+    ^ Complex real:r imaginary:imaginary
+
+    "
+     (1 % 1) + 1.0  
+     1.0 + (1 % 1)  
+    "
 !
 
-sumFromFraction: argument
-	^ argument asComplex + self
+sumFromFraction: aFraction
+    ^ aFraction asComplex + self
 !
 
-sumFromInteger: argument
-	^ argument asComplex + self
+sumFromInteger: anInteger
+    ^ anInteger asComplex + self
 ! !
 
 !Complex methodsFor:'mathematical functions'!
 
 angle
-	"Return the radian angle for this Complex number."
+    "Return the radian angle for this Complex number."
 
-	real < 0 ifTrue: [
-	    imaginary < 0 ifTrue: [
-		^ (imaginary / real) arcTan - Float pi
-	    ].
-	    ^ Float pi + (imaginary / real) arcTan
-	].
-	^ (imaginary / real) arcTan
+    real < 0 ifTrue: [
+        imaginary < 0 ifTrue: [
+            ^ (imaginary / real) arcTan - Float pi
+        ].
+        ^ Float pi + (imaginary / real) arcTan
+    ].
+    ^ (imaginary / real) arcTan
+
+    "
+     (1 % 1) angle radiansToDegrees
+    "
 !
 
 exp
-	"Return the complex exponential of the receiver."
+    "Return the complex exponential of the receiver."
 
-	^ imaginary cos % imaginary sin * real exp
+    ^ (imaginary cos % imaginary sin) * real exp
 !
 
 sqrt
-	"Return the square root of the receiver"
+    "Return the square root of the receiver"
+
+    | w quotient absReal absImag |
+
+    ((real = 0) and: [ imaginary = 0 ]) ifTrue: [ 
+        ^ Complex zero 
+    ].
+    absReal := real abs.
+    absImag := imaginary abs.
+
+    absReal >= absImag ifTrue:[ 
+        quotient := imaginary / real.
+        w := (absReal sqrt) * (((1 + (1 + (quotient * quotient)) sqrt) / 2) sqrt) 
+    ] ifFalse: [ 
+        quotient := real / imaginary.
+        w := (absImag sqrt) * (((quotient abs + (1 + (quotient * quotient)) sqrt) / 2) sqrt) 
+    ].
 
-	| u v |
-	(imaginary = 0 and: [real >= 0]) ifTrue: [^real sqrt].
-	v := (self abs - real / 2) sqrt.
-	u := imaginary / 2 / v.
-	^Complex real: u imaginary: v
+    real >= 0 ifTrue:[ 
+        ^ Complex real: w imaginary: (imaginary / (2 * w)) 
+    ].
+    imaginary >= 0 ifTrue: [ 
+        ^ Complex real: absImag / (2 * w) imaginary: w 
+    ].
+    ^ Complex real: absImag / (2 * w) imaginary: -1 * w
+!
+
+sqrt_bad
+    "Return the square root of the receiver"
 
-	"-4 asComplex sqrt"
-	"-4 asComplex sqrt squared"
+    | u v |
+
+    (imaginary = 0 and: [real >= 0]) ifTrue: [^ real sqrt].
+    v := (self abs - real / 2) sqrt.
+    u := imaginary / 2 / v.
+    ^ Complex real: u imaginary: v
+
+    "
+     -4 asComplex sqrt   
+     4 asComplex sqrt   
+    "
+    "
+     -4 asComplex sqrt squared 
+    "
 ! !
 
 !Complex methodsFor:'printing'!
 
+displayOn: aStream
+    aStream nextPut: $(.
+    self realPart printOn: aStream.
+    self imaginaryPart >= 0
+        ifTrue: [ aStream nextPut: $+ ]
+        ifFalse: [ aStream nextPut: $- ].
+    self imaginaryPart abs printOn: aStream.
+    aStream nextPutAll: 'i)'
+
+    "
+     Complex real:1 imaginary:1
+    "
+!
+
 printOn: aStream
-	aStream nextPut: $(.
-	real storeOn: aStream.
-	aStream nextPutAll: '%'.
-	imaginary storeOn: aStream.
-	aStream nextPut: $).
+    aStream nextPut: $(.
+    real storeOn: aStream.
+    aStream nextPutAll: '%'.
+    imaginary storeOn: aStream.
+    aStream nextPut: $).
 !
 
 printString
-	^ '(' , real printString, '%', imaginary printString, ')'
+    ^ '(' , real printString, '%', imaginary printString, ')'
 !
 
 storeOn: aStream
-	aStream nextPut: $(.
-	real storeOn: aStream.
-	aStream nextPutAll: '%'.
-	imaginary storeOn: aStream.
-	aStream nextPut: $).
+    self printOn:aStream
 ! !
 
 !Complex methodsFor:'private'!
 
 setReal: u setImaginary: v
-	real := u.
-	imaginary := v.
+    real := u.
+    imaginary := v.
 ! !
 
 !Complex methodsFor:'testing'!
 
 isComplex
+    "Answer whether the receiver has an imaginary part
+     (i.e. if it is a complex number). Always true here."
 
-	^true
+    ^ true
 !
 
 isReal
-	"Return true if this Complex number has a zero imaginary part."
-	^ imaginary = 0
+    "Return true if this Complex number has a zero imaginary part."
+
+    ^ imaginary = 0
 !
 
 isZero
-	"Answer whether 'self = self class zero'.  We can't use #= because
-	#= is defined in terms of #isZero"
+    "Answer whether 'self = self class zero'.  
+     We can't use #= because #= is defined in terms of #isZero"
 
-	^real isZero and: [imaginary isZero]
+    ^real isZero and: [imaginary isZero]
 !
 
 sign
+    "return a new complex, consisting of the signs of the real and imaginary parts"
 
-	^Complex real: real sign imaginary: imaginary sign
+    ^ Complex real: real sign imaginary: imaginary sign
+! !
+
+!Complex methodsFor:'truncation & rounding'!
+
+ceiling
+    "blocked: complex numbers have no ceiling"
+
+    ^ self shouldNotImplement
+!
+
+floor
+    "blocked: complex numbers have no floor"
+
+    ^ self shouldNotImplement
 ! !
 
 !Complex class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Complex.st,v 1.7 2003-04-22 09:44:13 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Complex.st,v 1.8 2003-06-16 09:13:42 cg Exp $'
 ! !