The number hierarchy provides a common protocol for many numeric types. Smalltalk automatically converts between internal representations and provides unlimited precision integer arithmetic.
The most useful numeric classes are:
Smalltalks numeric classes make good use of polymorphism in the language:
instances of all numeric classes may be used interchangable in most
operations (however, for some, it does not make sense).
Also, results of arithmetic (and other) operations are converted as
appropriate. For example, executing:
(send the message 'divide by 3' to the integer '1')
will return a fractional result, represented by an instance of
1 / 3
Fraction.
Protocol common to all numbers is:
result := number1 + number2
result := number1 - number2
result := number1 * number2
result := number1 / number2
result := number1 // number2 (truncate result)
result := number1 \ number2 (remainder)
result := number1 \\ number2 (integer remainder)
result := number negated
result := number abs
result := number sign
result := number sqrt (square root)
result := number truncated
result := number floor
result := number ceiling
result := number rounded
result := number factorial
result := integer1 gcd:integer2 (greatest common divisor)
result := integer1 lcm:integer2 (least common multiple)
result := number1 min:number2
result := number1 max:number2
boolResult := number negative
boolResult := number even
boolResult := number odd
boolResult := number1 > number2
boolResult := aNumber between:lowBounds and:highBounds
result := number sin
result := number cos
result := number arcSin (many other trigonometric operations)
result := integer1 bitAnd: integer2
result := integer1 bitOr: integer2
result := integer1 bitShift: count
result := integer1 bitXor: integer2
aNumber := Number readFrom:aStringOrStream onError:replacementValue
aNumber := Number readFrom:aStringOrStream
anInteger := Integer readFrom:aStringOrStream
aString := aNumber printString
aString := anInteger printStringRadix:radixInteger
aFloat := aNumber asFloat
anInteger := aNumber asInteger
aFraction := aNumber asFraction
More details are found in the
"Number class documentation".
Integer itself, but instead
of one of its subclasses, SmallInteger
or LargeInteger.
SmallInteger represents integers which fit into one
machine word (typically 31 bit (*)).
Storage of smallIntegers is very space efficient: in contrast to all other objects, smallIntegers are technically not represented by a pointer to the object, but instead the value is encoded in the pointer itself. Since one bit is required to distinguish smallIntegers from object references, one bit is lost for the storage of the integers value. Therefore, the smallInteger range is typically only -2^30 to 2^30-1.
LargeInteger represents integers which are out
of the valid smallInteger range. They can represent arbitrary values
(i.e. beside memory limitations, the valid range of largeIntegers is not
limited).
More details are found in
"Integer's class documentation", in
"SmallInteger's class documentation" and in
"LargeInteger's class documentation".
(1 / 3) * 3 = 1
while the corresponding float operation:
(1 / 33) asFloat * 33
may return 0.999999... on some systems due to rounding errors.
Fractional results from arithmetic operations are automatically reduced; therefore,
gives a result of
(1 / 3) * (1 / 3) * 3
1/3 (not 3/9).
Beside memory limitations, the precision of fractional numbers is unlimited.
More details are found in the
"Fraction class documentation".
double implementation.
Typically, the precision of floats is 64bit (i.e. some 15 digits)
- but you should not
depend on this being true for all implementations. See the C-compilers
documentation of your actual system for more information.
A companion class called ShortFloat is also available,
which corresponds to the C-compilers float implementation.
Typically, this gives you a precision of 32bit (i.e. roughly 6 digits).
Due to historic reasons, the existing smalltalk systems provide different
precision and/or names for their float number classes;
For portability, ST/X's
Notes:
The original ST-80 provided a single Float class, which offered
32bit floats.
ObjectWorks added a Double class, providing 64bit of precision.
ST/V's and VisualAge provide 64bit of precision
in their Float class.
Float class has 64bit precision,
and it provides Double as an alias.
Since having more precision does usually no harm to the program,
this choice should ease porting of smalltalk code from any system.
However, be aware of the fact that a float in ST/X takes up
more memory than a float in ST-80.
More details are found in
"Float's class documentation"
and
"ShortFloat's class documentation".
Others
You can extent the Number hierarchy, by adding new classes which
implement a certain minimum protocol (they should know how to perform
some of the basic arithmetic operations, and how to be converted into
other representations).
As an example, see the implementation of a complex class in
the file "goodies/Numeric-Complex.st".
(*)
One bit is lost for implementation reasons.
Therefore, the number of bits in a smallInteger is
the machines native integer size minus one; usually 31 (63 on DEC-alpha/osf1).
(
for details, see object representation)
Copyright © 1996 Claus Gittinger Development & Consulting
Doc $Revision: 1.22 $ $Date: 2001/08/23 12:12:36 $