SqueakByExample:8.2

From 흡혈양파의 번역工房
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Number

놀랍게도, 스몰토크에서의 숫자들은 원시데이터가 아닌 진짜 객체 입니다. 물론 숫자들은 가상 머신에서 효과적으로 동작합니다만, Number 의 계층은 스몰토크 클래스 계층의 다른 부분들처럼 완전하게 접근 및 확장이 가능합니다.

Number(숫자형)과 관련된 내용은 kernel-number 카테고리에서 찾을 수 있습니다. 이 계층의 상위는 Magnitude 이며, Magnitude 는 비교 연산자를 지원하는 모든 종류의 클래스들을 의미합니다. Number 는 다양한 산술 요소를 추가할 수 있습니다. 이런 연산자의 대부분이 추상메서드 입니다. Float 와 Fraction 은 각각 부동소수점(실수)과 분수를 나타냅니다. Integer 또한 추상클래스 이며, 추상클래스인 Integer 는 하위 클래스인 SmallInteger, LagePositiveInteger, LargeNegativeInteger 등과는 다르게 구별됩니다. 일반적인 경우, 값이 요구하는 만큼 자동으로 변환되므로, 유저들은 3 개의 정수 클래스들 사이의 차이점들에 대해 신경을 써야 할 필요는 없습니다.

그럼 8.1: 숫자구조도(class구조)


Magnitude

Magnitude 는 Number 클래스의 부모클래스일 뿐만 아니라 Character, Duration, Timespan 처럼 연산을 지원하는 클래스들의 부모이기도 합니다.(Complex(복소수)는 비교가 불가능합니다. 그래서 Number 를 상속받지는 않습니다)

< 과 = 메서드는 추상메서드입니다. 그외 다른 연산자들은 일반적인 방법으로 정의됩니다. 예를 들자면 다음과 같습니다:

메서드 8.12: 추상 비교 메서드

Magnitude>> < aMagnitude
  "Answer whether the receiver is less than the argument."
  self subclassResponsibility

Magnitude>> > aMagnitude
  "Answer whether the receiver is greater than the argument."
  aMagnitude < self


Number

Magnitude 비슷하게 Number 에서 +, -, *, / 등은 추상메서드로 정의합니다만, 그외의 다른 산술 연산자들은 일반형적 형태로 정의됩니다.

모든 Number 객체들은 asFloat 과 asInteger 같은 다양한 변환 연산자를 지원합니다. 이런 연산자중에는, Number 를 실수부가 0 인 복소수의 인스턴스로 변환하는 i 나, Number 에서 Duration 객체를 생성하는 hour, day, week 등이 있습니다.

Number 는 sin, log, raiseTo:, squared, sqrt 등과 같은 일반 수학 기능을 직접 지원합니다.

Number>>printOn: 은 Number>>printOn:base: 의 추상메서드로 구현되어 있습니다(Number>>printOn: 의 경우 base에 해당되는 기본값은 10으로 지정되어 있습니다.)

Testing 메서드의 종류에는, even, odd, positive, negative 등이 있습니다. 당연히, Number 는 isNumber를 재지정(override)하고 있습니다. 재미있는 점은 isInfinite 는 false 를 반환하도록 정의되어 있다는 것입니다.

Truncation 메서드에는 floor, ceiling, intergerPart, fractionPart 등이 있습니다.

1 + 2.5 ⇒ 3.5 "Addition of two numbers"
3.4 * 5 ⇒ 17.0 "Multiplication of two numbers"
8/2 ⇒ 4 "Division of two numbers"
10 -- 8.3 ⇒ 1.7 "Subtraction of two numbers"
12 = 11 ⇒ false "Equality between two numbers"
12 ∼= 11 ⇒ true "Test if two numbers are different"
12 > 9 ⇒ true "Greater than"
12 >= 10 ⇒ true "Greater or equal than"
12 < 10 ⇒ false "Smaller than"
100@10 ⇒ 100@10 "Point creation"


다음 예제는 스몰토크에서 문제없이 잘 작동합니다:

1000 factorial / 999 factorial        1000


1000 factorial 을 다른언어로 계산하는건 쉽지 않습니다만 별다른 어려움없이 계산이 된다는점을 주의해 주시기 바랍니다. 위의 예제는 숫자에 대한 자동 형변환과 정확한 숫자의 정확한 제어에 대한 좋은 예입니다.


Squeak comment.png1000 factorial 의 결과 출력을 시도해 보시기 바랍니다. 이 작업은 계산하는 것보다 출력에 더 많은 시간이 걸립니다.


Float

Float 는 부동소수점을 위한 Number 의 추상메서드로 구현되어 있습니다.

여기서 흥미로운점은 Float 클래스(예컨데 Float의 class-side)는 다음 정수를 반환합니다: e, infinity, nan, pi 등

Float pi ⇒ 3.141592653589793
Float infinity ⇒ Infinity
Float infinity isInfinite ⇒ true


Fraction

Fraction(분수) 은 분자와 분모에 쓰이는 인스턴스 변수들로 표시되며, 각 분자와 분모는 반드시 정수여야 합니다. 분수는 일반적으로 정수의 나눗셈으로 만들어 집니다. (Fraction>>numerator:denominator: 를 사용하는것 보다는 constructor 메서드가 낫습니다.)

6/8 ⇒ (3/4)
(6/8) class ⇒ Fraction


정수 또는 다른 분수로 분수를 곱하기 하면, 답이 정수가 될 수 있습니다.

6/8 * 4 ⇒ 3


Integer

Integer(정수) 는 3 개의 구체적 정수 구현에 대한 추상적 부모 클래스입니다. Integer 는 많은 추상 Number 메서드의 구체적인 구현을 제공할 뿐만 아니라, factorial, atRandom, isPrime, gcd 등의 정수 특유의 메서드 및 그외 많은 메서드를 추가합니다.

SmallInteger는 인스턴스가 간결하게 표시된다는 면에서 특별합니다-SmallInteger는 값을 참조로서 저장하는 대신, 참조를 유지하기 위해 비트 영역을 사용해 직접 표현합니다. 객체참조의 첫 번째 비트는 객체가 SmallInteger 인지 아닌지를 가리킵니다.

클래스 메서드 minVal 과 maxVal 은 SmallInteger 의 범위를 알려줍니다.

SmallInteger maxVal = ((2 raisedTo: 30) -- 1) ⇒ true
SmallInteger minVal = (2 raisedTo: 30) negated ⇒ true


SmallInteger 가 이 범위를 벗어나면, LargePositiveInteger 로 자동으로 변환되거나 또한 필요한 만큼 LargeNegetiveInteger 로 자동으로 변환됩니다:

(SmallInteger maxVal + 1) class ⇒ LargePositiveInteger
(SmallInteger minVal -- 1) class ⇒ LargeNegativeInteger


마찬가지로, 큰 정수들은 알맞은 시기에 작은 정수들로 다시 변환됩니다.

대부분의 프로그래밍 언어에서 처럼, 정수들은 지정동작의 반복에 유용합니다. 블록을 반복적으로 평가하는 작업에 사용되는 전용 메서드 timesRepeat 이 있습니다. 3장에서 비슷한 예제를 이미 본적이 있죠.

n := 2.
3 timesRepeat: [ n := n*n ].
n    256

Notes