# 8.2: Numbers

- Page ID
- 36373

Remarkably, numbers in Smalltalk are not primitive data values but true objects. Of course numbers are implemented efficiently in the virtual machine, but the `Number`

hierarchy is as perfectly accessible and extensible as any other portion of the Smalltalk class hierarchy.

Numbers are found in the *Kernel-Numbers *category. The abstract root of this hierarchy is `Magnitude`

, which represents all kinds of classes supporting comparision operators. `Number`

adds various arithmetic and other operators as mostly abstract methods. `Float`

and `Fraction`

represent, respectively, floating point numbers and fractional values. `Integer`

is also abstract, thus distinguishing between subclasses `SmallInteger`

, `LargePositiveInteger`

and `LargeNegativeInteger`

. For the most part users do not need to be aware of the difference between the three `Integer`

classes, as values are automatically converted as needed.

## Magnitude

`Magnitude`

is the parent not only of the `Number`

classes, but also of other classes supporting comparison operations, such as `Character`

, `Duration`

and `Timespan`

. (`Complex`

numbers are not comparable, and so do not inherit from `Number`

.)

Methods < and = are abstract. The remaining operators are generically defined. For example:

Code \(\PageIndex{1}\) (Squeak): *Abstract Comparison Methods *

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

Similarly, Number defines +, --, * and / to be abstract, but all other arithmetic operators are generically defined.

All `Number`

objects support various *converting *operators, such as `asFloat`

and `asInteger`

. There are also numerous *shortcut constructor methods*, such as `i`

, which converts a `Number`

to an instance of `Complex`

with a zero real component, and others which generate `Durations`

, such as `hour`

, `day`

and `week`

.

`Numbers`

directly support common *math functions *such as `sin`

, `log`

, `raiseTo:`

, `squared`

, `sqrt`

and so on.

*Number»printOn:* is implemented in terms of the abstract method *Number»printOn:base:*. (The default base is 10.)

Testing methods include `even`

, `odd`

, `positive`

and `negative`

. Unsurprisingly `Number`

overrides `isNumber`

. More interesting, `isInfinite`

is defined to return `false`

.

*Truncation *methods include `floor`

, `ceiling`

, `integerPart`

, `fractionPart`

and so on.

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"

The following example works surprisingly well in Smalltalk:

1000 factorial / 999 factorial → 1000

Note that `1000 factorial`

is really calculated which in many other languages can be quite difficult to compute. This is an excellent example of automatic coercion and exact handling of a number.

\(\bigstar\) *Try to display the result of *`1000 factorial`

*. It takes more time to display it than to calculate it! *

## Float

Float implements the abstract `Number`

methods for floating point numbers.

More interestingly, `Float`

class (*i.e.*, the class-side of `Float`

) provides methods to return the following *constants*: `e`

, `infinity`

, `nan`

and `pi`

.

Float pi → 3.141592653589793 Float infinity → Infinity Float infinity isInfinite → true

## Fraction

`Fractions`

are represented by instance variables for the numerator and denominator, which should be `Integers`

. Fractions are normally created by `Integer`

division (rather than using the constructor method *Fraction»numerator:denominator:*):

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

Multiplying a `Fraction`

by an `Integer`

or another `Fraction`

may yield an `Integer`

:

6/8*4 → 3

## Integer

`Integer`

is the abstract parent of three concrete integer implementations. In addition to providing concrete implementations of many abstract `Number`

methods, it also adds a few methods specific to integers, such as `factorial`

, `atRandom`

, `isPrime`

, `gcd:`

and many others.

`SmallInteger`

is special in that its instances are represented compactly — instead of being stored as a reference, a `SmallInteger`

is represented directly using the bits that would otherwise be used to hold a reference. The first bit of an object reference indicates whether the object is a `SmallInteger`

or not.

The class methods `minVal`

and `maxVal`

tell us the range of a `SmallInteger`

:

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

When a `SmallInteger`

goes out of this range, it is automatically converted to a `LargePositiveInteger`

or a `LargeNegativeInteger`

, as needed:

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

Large integers are similarly converted back to small integers when appropriate.

As in most programming languages, integers can be useful for specifying iterative behaviour. There is a dedicated method *timesRepeat:* for evaluating a block repeatedly. We have already seen a similar example in Chapter 3:

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