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
30 bits fixnum representation
|........................|00
|-----|-----|-----|------+--|
byte3 byte2 byte1 byte0
the two least significant bits are set to zero: this “tags” the machine words which embed fixnums.
61 bits fixnum representation
|...............................................|000
|-----|-----|-----|-----|-----|-----|-----|-----+---|
byte7 byte6 byte5 byte4 byte3 byte2 byte1 byte0
the three least significant bits are set to zero: this “tags” the machine words which embed fixnums.
The fixnums tag is 00 on 32-bit platforms and 000 on
64-bit platforms; given the symbols:
fx_shiftfx_scalethe 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.
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.
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.
Examples:
long int N = 123L;
ikptr P = IK_FIX(N);
long int M = IK_UNFIX(P);
Convert a small exact integer in the correct range for a fixnum, into a
ikptrvalue. num is cast tolong int.NOTE The macrofixis defined only in the internal header file and its usage is deprecated.