SqueakByExample:8.2

From 흡혈양파의 번역工房
Jump to: navigation, search

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