Removed the notion of a "large" context. For simplicity, all contexts
[panda.git] / st / Number.st
blob82ceb38464e2c9a52e4893422e4decf03aff8721
2 Copyright (c) 2008 Vincent Geddes
3 Copyright (c) 2008 Luca Bruno
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the 'Software'), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
21 DEALINGS IN THE SOFTWARE.
24 "constants"
26 Number classMethod!
28         ^ 3.1415926535897932384626433832795028841971693993751!
30 Number classMethod!
32         ^ 2.7182818284590452353602874713526624977572470937000!
34 "instance creation"
36 Number classMethod!
37 new
38     self shouldNotImplement!
41 "testing"
43 Number method!
44 isNumber
45     ^ true!
47 Number method!
48 isInteger
49     ^ false!
51 Number method!
52 isSmallInteger
53     ^ false!
55 Number method!
56 isLargeInteger
57     ^ false!
59 Number method!
60 isFloat
61     ^ false!
63 Number method!
64 isFraction
65     ^ false!
67 Number method!
68 isZero
69     ^ self = self zero!
71 Number method!
72 isNegative
73     ^ self < self zero!
75 Number method!
76 isPositive
77     ^ self >= self zero!
79 Number method!
80 isStrictlyPositive
81     ^ self > self zero!
83 Number method!
84 sign
85     self < self zero ifTrue: [^ -1].
86     self > self zero ifTrue: [^  1].
87     ^ 0!
89 "intervals"
91 Number method!
92 to: stop
93     "Create an Interval between the receiver and stop"
94     ^ Interval from: self to: stop!
96 Number method!
97 to: stop by: step
98     "Create an Interval between the receiver and stop by step"
99     ^ Interval from: self to: stop by: step!
101 Number method!
102 to: stop do: aBlock
103     "Do aBlock from self to stop. Pass the counter to aBlock"
104     self to: stop by: self unity do: aBlock!
106 Number method!
107 to: stop reverseDo: aBlock
108     "Do aBlock decreasing self to stop. Pass the counter to aBlock"
109     self to: stop by: self unity reverseDo: aBlock!
111 Number method!
112 to: stop by: step do: aBlock
113     "Do aBlock increasing self to stop stepping by step. Pass the counter to aBlock"
114     | i |
115     i := self.
116     step isPositive
117         ifTrue: [
118             [ i <= stop ]
119                 whileTrue: [ aBlock value: i.
120                              i := i + step ] ]
121         ifFalse: [
122             [ i >= stop ]
123                 whileTrue: [ aBlock value: i.
124                              i := i + step ] ]!
126 Number method!
127 to: stop by: step reverseDo: aBlock
128     "Do aBlock decreasing self to stop stepping by step. Pass the counter to aBlock"
129     | i |
130     i := self.
131     step isPositive
132         ifTrue: [
133             [ i >= stop ]
134                 whileTrue: [ aBlock value: i.
135                              i := i - step ] ]
136         ifFalse: [
137             [ i <= stop ]
138                 whileTrue: [ aBlock value: i.
139                              i := i - step ] ]!
142 "coercing"
144 Number method!
145 asFraction
146     ^ Fraction numerator: self denominator: 1!
148 Number method!
149 asNumber
150     ^ self!
152 Number method!
153 asInteger
154     self subclassResponsibility!
156 Number method!
157 asFloat
158     self subclassResponsibility!
160 Number method!
161 zero
162     ^ self subclassResponsibility!
164 Number method!
165 generality
166     self subclassResponsibility!
168 Number method!
169 unity
170     self subclassResponsibility!
172 Number method!
173 coerce: aNumber
174     ^ aNumber!
177 "arithmetic"
179 Number method!
180 negated
181     self ~= self zero
182                 ifTrue: [ ^ self zero - self ]!
184 Number method!
186     self < self zero
187                 ifTrue: [ ^ self negated ]
188                 ifFalse: [ ^ self ]!
190 Number method!
191 reciprocal
192     "Answer the reciprocal number of self"
193     ^ 1 / self!
195 Number method!
196 + aNumber
197     "Coerce aNumber and do the sum"
198     ^ self generality > aNumber generality
199                 ifTrue: [ self + (self coerce: aNumber) ]
200                 ifFalse: [ (aNumber coerce: self) + aNumber ]!
202 Number method!
203 - aNumber
204     "Coerce aNumber and do the difference"
205     ^ self generality > aNumber generality
206                 ifTrue: [ self - (self coerce: aNumber) ]
207                 ifFalse: [ (aNumber coerce: self) - aNumber ]!
209 Number method!
210 * aNumber
211     "Coerce aNumber and do multiplication"
212     ^ self generality > aNumber generality
213                 ifTrue: [ self * (self coerce: aNumber) ]
214                 ifFalse: [ (aNumber coerce: self) * aNumber ]!
216 Number method!
217 / aNumber
218     "Coerce aNumber and do division"
219     aNumber isZero
220         ifTrue: [ self zeroDivide ].
222     ^ self generality > aNumber generality
223         ifTrue: [ self / (self coerce: aNumber) ]
224         ifFalse: [ (aNumber coerce: self) / aNumber ]!
226 Number method!
227 // aNumber
228     "Do division then answer the quotient floor"
229     ^ (self / aNumber) floor!
231 Number method!
232 \\ aNumber
233     "Coerce aNumber and do modulo"
234     ^ self generality > aNumber generality
235                 ifTrue: [ self \\ (self coerce: aNumber) ]
236                 ifFalse: [ (aNumber coerce: self) \\ aNumber ]!
238 Number method!
239 quo: aNumber
240     "Do division then answer the truncated quotient towards zero"
241     ^ (self / aNumber) truncated!
243 Number method!
244 rem: aNumber
245     "Do division then answer the truncated remainder towards zero"
246     self notYetImplemented!
249 "comparing"
251 Number method!
252 compare: aNumber
253     "Return 1 if self > aNumber, 0 if = aNumber, -1 if < aNumber"
254     self > aNumber ifTrue: [ ^ 1 ].
255     self = aNumber ifTrue: [ ^ 0 ].
256     self < aNumber ifTrue: [ ^ -1 ]!
258 Number method!
259 < aNumber
260     "Coerce aNumber and compare"
261     ^ self generality > aNumber generality
262                 ifTrue: [ self < (self coerce: aNumber) ]
263                 ifFalse: [ (aNumber coerce: self) < aNumber ]!
265 Number method!
266 > aNumber
267     "Coerce aNumber and compare"
268     ^ self generality > aNumber generality
269                 ifTrue: [ self > (self coerce: aNumber) ]
270                 ifFalse: [ (aNumber coerce: self) > aNumber ]!
272 Number method!
273 <= aNumber
274     "Coerce aNumber and compare"
275     ^ self generality > aNumber generality
276                 ifTrue: [ self <= (self coerce: aNumber) ]
277                 ifFalse: [ (aNumber coerce: self) <= aNumber ]!
279 Number method!
280 >= aNumber
281     "Coerce aNumber and compare"
282     ^ self generality > aNumber generality
283                 ifTrue: [ self >= (self coerce: aNumber) ]
284                 ifFalse: [ (aNumber coerce: self) >= aNumber ]!
286 Number method!
287 = aNumber
288     "Coerce aNumber and compare equality"
289     aNumber isNumber
290                 ifFalse: [ ^ false ].
291     ^ self generality > aNumber generality
292                 ifTrue: [ self = (self coerce: aNumber) ]
293                 ifFalse: [ (aNumber coerce: self) = aNumber ]!
295 Number method!
296 ~= aNumber
297     "Coerce aNumber and compare inequality"
298     ^ self generality > aNumber generality
299                 ifTrue: [ self ~= (self coerce: aNumber) ]
300                 ifFalse: [ (aNumber coerce: self) ~= aNumber ]!
304 "signaling"
306 Number method!
307 zeroDivide
308     self error: 'division by zero'!
311 "mathematics"
312 Number method!
313 floor
314         "Answer the integer nearest the receiver toward negative infinity."
316         | truncation |
318         truncation := self truncated.
319         self >= 0 ifTrue: [^truncation].
320         self = truncation
321                 ifTrue: [^truncation]
322                 ifFalse: [^truncation - 1]!
324 Number method!
326     ^ self asFloat exp!
328 Number method!
330     ^ self asFloat ln!
332 Number method!
333 log: aNumber
334         ^ self ln / aNumber ln!
336 Number method!
337 floorLog: radix
338     self notYetImplemented!
340 Number method!
341 raisedTo: aNumber
342     self notYetImplemented!
344 Number method!
345 raisedToInteger: anInteger
346     self notYetImplemented!
348 Number method!
349 sqrt
350     ^ self asFloat sqrt!
352 Number method!
354     ^ self asFloat sin!
356 Number method!
358     ^ self asFloat cos!
360 Number method!
362     ^ self asFloat tan!
364 Number method!
365 arcSin
366     ^ self asFloat arcSin!
368 Number method!
369 arcCos
370     ^ self asFloat arcCos!
372 Number method!
373 arcTan
374     ^ self asFloat arcTan!
376 Number method!
377 squared
378     "Answer the square of the receiver"
379     ^ self * self!
381 Number method!
382 raisedToInteger: anInteger
383         | count result |
385         self = 0
386                 ifTrue: [ ^ self zero ].
387         (self = 1) | (anInteger = 0)
388                 ifTrue: [ ^ self unity ].
390         anInteger isNegative
391                 ifTrue: [ ^ (self raisedToInteger: anInteger abs) reciprocal ].
393         result := 1.
394         count := 0.
395         [ (count := count + 1) <= anInteger ]
396                 whileTrue: [ result := result * self ].
398         ^ result!
400 Number method!
401 raisedTo: aNumber
403         self = 0
404                 ifTrue: [ ^ self zero ].
405         (self = 1) | (aNumber = 0)
406                 ifTrue: [ ^ self unity ].
408         (aNumber isFloat) & (self isNegative)
409                 ifTrue: [ self error: 'raising a negative number to non-integral exponent'].
411         aNumber isFloat
412                 ifTrue: [ ^ (aNumber * self ln) exp ].
414         ^ self raisedToInteger: aNumber!
416 "printing"
418 Number method!
419 printStringBase: anInteger
420     "Answer a String representation of the receiver"
421     | stream |
422     stream := WriteStream on: (String new: 20).
423     self printOn: stream base: anInteger.
424     ^ stream contents!
426 Number method!
427 printOn: aStream base: anInteger
428         self subclassResponsibility!
430 Number method!
431 printOn: aStream
432         self printOn: aStream base: 10!