Added basic FileStream implementation. Object hash values are now
[panda.git] / st / Number.st
blob41eafd4af7d530b9352616cec9aacb91a201e37d
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 "instance creation"
26 Number classMethod!
27 new
28     self shouldNotImplement!
31 "testing"
33 Number method!
34 isNumber
35     ^ true!
37 Number method!
38 isInteger
39     ^ false!
41 Number method!
42 isSmallInteger
43     ^ false!
45 Number method!
46 isLargeInteger
47     ^ false!
49 Number method!
50 isFloat
51     ^ false!
53 Number method!
54 isFraction
55     ^ false!
57 Number method!
58 isZero
59     ^ self = self zero!
61 Number method!
62 isNegative
63     ^ self < self zero!
65 Number method!
66 isPositive
67     ^ self >= self zero!
69 Number method!
70 isStrictlyPositive
71     ^ self > self zero!
73 Number method!
74 sign
75     self < self zero ifTrue: [^ -1].
76     self > self zero ifTrue: [^  1].
77     ^ 0!
79 "intervals"
81 Number method!
82 to: stop
83     "Create an Interval between the receiver and stop"
84     ^ Interval from: self to: stop!
86 Number method!
87 to: stop by: step
88     "Create an Interval between the receiver and stop by step"
89     ^ Interval from: self to: stop by: step!
91 Number method!
92 to: stop do: aBlock
93     "Do aBlock from self to stop. Pass the counter to aBlock"
94     self to: stop by: self unity do: aBlock!
96 Number method!
97 to: stop reverseDo: aBlock
98     "Do aBlock decreasing self to stop. Pass the counter to aBlock"
99     self to: stop by: self unity reverseDo: aBlock!
101 Number method!
102 to: stop by: step do: aBlock
103     "Do aBlock increasing self to stop stepping by step. Pass the counter to aBlock"
104     | i |
105     i := self.
106     step isPositive
107         ifTrue: [
108             [ i <= stop ]
109                 whileTrue: [ aBlock value: i.
110                              i := i + step ] ]
111         ifFalse: [
112             [ i >= stop ]
113                 whileTrue: [ aBlock value: i.
114                              i := i + step ] ]!
116 Number method!
117 to: stop by: step reverseDo: aBlock
118     "Do aBlock decreasing self to stop stepping by step. Pass the counter to aBlock"
119     | i |
120     i := self.
121     step isPositive
122         ifTrue: [
123             [ i >= stop ]
124                 whileTrue: [ aBlock value: i.
125                              i := i - step ] ]
126         ifFalse: [
127             [ i <= stop ]
128                 whileTrue: [ aBlock value: i.
129                              i := i - step ] ]!
132 "coercing"
134 Number method!
135 asFraction
136     ^ Fraction numerator: self denominator: 1!
138 Number method!
139 asNumber
140     ^ self!
142 Number method!
143 asInteger
144     self subclassResponsibility!
146 Number method!
147 asFloat
148     self subclassResponsibility!
150 Number method!
151 zero
152     ^ self subclassResponsibility!
154 Number method!
155 generality
156     self subclassResponsibility!
158 Number method!
159 unity
160     self subclassResponsibility!
162 Number method!
163 coerce: aNumber
164     ^ aNumber!
167 "arithmetic"
169 Number method!
170 negated
171     self ~= self zero
172                 ifTrue: [ ^ self zero - self ]!
174 Number method!
176     self < self zero
177                 ifTrue: [ ^ self negated ]
178                 ifFalse: [ ^ self ]!
180 Number method!
181 reciprocal
182     "Answer the reciprocal number of self"
183     ^ 1 / self!
185 Number method!
186 + aNumber
187     "Coerce aNumber and do the sum"
188     ^ self generality > aNumber generality
189                 ifTrue: [ self + (self coerce: aNumber) ]
190                 ifFalse: [ (aNumber coerce: self) + aNumber ]!
192 Number method!
193 - aNumber
194     "Coerce aNumber and do the difference"
195     ^ self generality > aNumber generality
196                 ifTrue: [ self - (self coerce: aNumber) ]
197                 ifFalse: [ (aNumber coerce: self) - aNumber ]!
199 Number method!
200 * aNumber
201     "Coerce aNumber and do multiplication"
202     ^ self generality > aNumber generality
203                 ifTrue: [ self * (self coerce: aNumber) ]
204                 ifFalse: [ (aNumber coerce: self) * aNumber ]!
206 Number method!
207 / aNumber
208     "Coerce aNumber and do division"
209     aNumber isZero
210         ifTrue: [ self zeroDivide ].
212     ^ self generality > aNumber generality
213         ifTrue: [ self / (self coerce: aNumber) ]
214         ifFalse: [ (aNumber coerce: self) / aNumber ]!
216 Number method!
217 // aNumber
218     "Do division then answer the quotient floor"
219     ^ (self / aNumber) floor!
221 Number method!
222 \\ aNumber
223     "Coerce aNumber and do modulo"
224     ^ self generality > aNumber generality
225                 ifTrue: [ self \\ (self coerce: aNumber) ]
226                 ifFalse: [ (aNumber coerce: self) \\ aNumber ]!
228 Number method!
229 quo: aNumber
230     "Do division then answer the truncated quotient towards zero"
231     ^ (self / aNumber) truncated!
233 Number method!
234 rem: aNumber
235     "Do division then answer the truncated remainder towards zero"
236     self notYetImplemented!
239 "comparing"
241 Number method!
242 compare: aNumber
243     "Return 1 if self > aNumber, 0 if = aNumber, -1 if < aNumber"
244     self > aNumber ifTrue: [ ^ 1 ].
245     self = aNumber ifTrue: [ ^ 0 ].
246     self < aNumber ifTrue: [ ^ -1 ]!
248 Number method!
249 < aNumber
250     "Coerce aNumber and compare"
251     ^ self generality > aNumber generality
252                 ifTrue: [ self < (self coerce: aNumber) ]
253                 ifFalse: [ (aNumber coerce: self) < aNumber ]!
255 Number method!
256 > aNumber
257     "Coerce aNumber and compare"
258     ^ self generality > aNumber generality
259                 ifTrue: [ self > (self coerce: aNumber) ]
260                 ifFalse: [ (aNumber coerce: self) > aNumber ]!
262 Number method!
263 <= aNumber
264     "Coerce aNumber and compare"
265     ^ self generality > aNumber generality
266                 ifTrue: [ self <= (self coerce: aNumber) ]
267                 ifFalse: [ (aNumber coerce: self) <= aNumber ]!
269 Number method!
270 >= aNumber
271     "Coerce aNumber and compare"
272     ^ self generality > aNumber generality
273                 ifTrue: [ self >= (self coerce: aNumber) ]
274                 ifFalse: [ (aNumber coerce: self) >= aNumber ]!
276 Number method!
277 = aNumber
278     "Coerce aNumber and compare equality"
279     aNumber isNumber
280                 ifFalse: [ ^ false ].
281     ^ self generality > aNumber generality
282                 ifTrue: [ self = (self coerce: aNumber) ]
283                 ifFalse: [ (aNumber coerce: self) = aNumber ]!
285 Number method!
286 ~= aNumber
287     "Coerce aNumber and compare inequality"
288     ^ self generality > aNumber generality
289                 ifTrue: [ self ~= (self coerce: aNumber) ]
290                 ifFalse: [ (aNumber coerce: self) ~= aNumber ]!
294 "signaling"
296 Number method!
297 zeroDivide
298     self error: 'division by zero'!
301 "mathematics"
302 Number method!
303 floor
304         "Answer the integer nearest the receiver toward negative infinity."
306         | truncation |
308         truncation := self truncated.
309         self >= 0 ifTrue: [^truncation].
310         self = truncation
311                 ifTrue: [^truncation]
312                 ifFalse: [^truncation - 1]!
314 Number method!
316     ^ self asFloat exp!
318 Number method!
320     ^ self asFloat ln!
322 Number method!
323 log: aNumber
324         ^ self ln / aNumber ln!
326 Number method!
327 floorLog: radix
328     self notYetImplemented!
330 Number method!
331 raisedTo: aNumber
332     self notYetImplemented!
334 Number method!
335 raisedToInteger: anInteger
336     self notYetImplemented!
338 Number method!
339 sqrt
340     ^ self asFloat sqrt!
342 Number method!
344     ^ self asFloat sin!
346 Number method!
348     ^ self asFloat cos!
350 Number method!
352     ^ self asFloat tan!
354 Number method!
355 arcSin
356     ^ self asFloat arcSin!
358 Number method!
359 arcCos
360     ^ self asFloat arcCos!
362 Number method!
363 arcTan
364     ^ self asFloat arcTan!
366 Number method!
367 squared
368     "Answer the square of the receiver"
369     ^ self * self!
371 Number method!
372 raisedToInteger: anInteger
373         | count result |
375         self = 0
376                 ifTrue: [ ^ self zero ].
377         (self = 1) | (anInteger = 0)
378                 ifTrue: [ ^ self unity ].
380         anInteger isNegative
381                 ifTrue: [ ^ (self raisedToInteger: anInteger abs) reciprocal ].
383         result := 1.
384         count := 0.
385         [ (count := count + 1) <= anInteger ]
386                 whileTrue: [ result := result * self ].
388         ^ result!
390 Number method!
391 raisedTo: aNumber
393         self = 0
394                 ifTrue: [ ^ self zero ].
395         (self = 1) | (aNumber = 0)
396                 ifTrue: [ ^ self unity ].
398         (aNumber isFloat) & (self isNegative)
399                 ifTrue: [ self error: 'raising a negative number to non-integral exponent'].
401         aNumber isFloat
402                 ifTrue: [ ^ (aNumber * self ln) exp ].
404         ^ self raisedToInteger: aNumber!
406 "printing"
408 Number method!
409 printStringBase: anInteger
410     "Answer a String representation of the receiver"
411     | stream |
412     stream := WriteStream on: (String new: 20).
413     self printOn: stream base: anInteger.
414     ^ stream contents!
416 Number method!
417 printOn: aStream base: anInteger
418         self subclassResponsibility!
420 Number method!
421 printOn: aStream
422         self printOn: aStream base: 10!