Next: , Previous: objects booleans, Up: objects


12.5 Fixnum objects

Fixnums are “small” exact integers which fit in a single machine word: if the word size is 4, 30 bits are used for fixnum representation; else the word size is 8 and 61 bits are used for fixnum representation. On a 32-bit platform, 30 bits are available to store the number:

     (greatest-fixnum)       ⇒ +536870911
     (expt 2 29)             ⇒ +536870912
     (- (expt 2 29) 1)       ⇒ +536870911
     
     (least-fixnum)          ⇒ -536870912
     (- (expt 2 29))         ⇒ -536870912

The fixnums tag is 00 on 32-bit platforms and 000 on 64-bit platforms; given the symbols:

fx_shift
Set to the number of bits in the tag.
fx_scale
Set to the number of bytes in a machine word.

the value is selected in such a way that:

     length_in_bytes = number_of_words *  fx_scale
                     = number_of_words *  wordsize
                     = number_of_words << fx_shift

this allows us, for example, to take the fixnum representing the number of items in a vector and consider it directly as size of the vector's data area in bytes.

Basic operations

Given an exact integer stored in a long value with the right amount of bits, we encode a fixnum as follows:

     long    the_value  = ...;
     ikptr   the_fixnum = (ikptr)(the_value << fx_shift);

and we decode it as follows:

     ikptr   the_fixnum = ...;
     long    the_value  = (long)(the_fixnum >> fx_shift);

to verify if a ikptr is a fixnum we do:

     ikptr   the_fixnum = ...;
     
     if (fx_tag == ((long)the_fixnum & fx_mask))
       it_is_a_fixnum();
     else
       it_is_not();

it is better to use the convenience macros described below.

— Macro: fx_tag 0

The fixnums tag.

— Macro: fx_shift

The number of bits in the fixnums tag. It is the amount of bits we have to left–shift a machine word to encode its value as fixnum.

— Macro: fx_mask

Bit mask used to isolate the tag bits of a fixnum.

Convenience preprocessor macros

Examples:

     long int  N = 123L;
     ikptr     P = IK_FIX(N);
     long int  M = IK_UNFIX(P);
— Preprocessor Macro: ikptr IK_FIX (num)
— Preprocessor Macro: ikptr fix (num)

Convert a small exact integer in the correct range for a fixnum, into a ikptr value. num is cast to long int.

NOTE The macro fix is defined only in the internal header file and its usage is deprecated.

— Preprocessor Macro: long IK_UNFIX (ikptr ref)
— Preprocessor Macro: long unfix (ikptr ref)

Convert an ikptr value holding a fixnum into a fixnum of type long int.

NOTE The macro unfix is defined only in the internal header file and its usage is deprecated.

— Preprocessor Macro: int IK_IS_FIXNUM (ikptr ref)

Expand to true if ref is an ikptr embedding a fixnum. It just tests if the least significant bits in the tag are set to zero.