Next: , Previous: , Up: objects   [Index]


13.17 Compnum objects

Compnums are complex numbers having a fixnum, bignum, ratnum or flonum as real part and a fixnum, bignum, ratnum or flonum as imaginary part, but not both flonums. The imaginary part of a compnum object is never the exact zero.

A compnum is a fixed length memory block referenced by machine words tagged as vectors. The first machine word of a compnum block is tagged has compnum in its least significant bits and it has the most significant bits set to zero.

|------------------------|-------------| reference to compnum
      heap pointer         vector tag

|------------------------|-------------| compnum first word
   all set to zero         compnum tag

A compnum memory block is 4 words wide; a reference to the real part is stored in the second word and a reference to the imaginary part is stored in the third word

   1st word     2nd word     3rd word     4th word
|------------|------------|------------|------------|
 tagged word   real part    imag part     unused

Basic operations

Compnums are allocated on the Scheme heap as follows:

ikpcb_t * pcb   = ik_the_pcb();
ikptr_t   s_cn;

s_cn = ik_safe_alloc(pcb, compnum_size) | vector_tag;
IK_COMPNUM_TAG(s_cn) = compnum_tag;

after allocation we must always initialise the real and imaginary parts to some correct value before running the next garbage collection; a full allocation and initialisation is as follows:

ikpcb_t * pcb  = ik_the_pcb();
ikptr_t   s_re = the_real;
ikptr_t   s_im = the_imag;
ikptr_t   s_cn;

pcb->root9 = &s_re;
pcb->root8 = &s_im;
{
  s_rn = ik_safe_alloc(pcb, compnum_size) | vector_tag;
}
pcb->root8 = NULL;
pcb->root9 = NULL;

IK_COMPNUM_TAG(s_cn)  = compnum_tag;
IK_COMPNUM_REAL(s_cn) = s_re;
IK_COMPNUM_IMAG(s_cn) = s_im;

notice that, as in this example, when a new compnum object is allocated after the allocation of the real and imaginary objects: we do not need to call ik_signal_dirt_in_page_of_pointer() for s_cn because the compnum is on the Scheme heap’s nursery, so it will for sure be scanned at the next garbage collection.

If we allocate the compnum object first, then the real and imaginary objects, we want to follow this pattern:

ikpcb_t *  pcb  = ik_the_pcb();
iksword_t  rep  = the_real_part;
iksword_t  imp  = the_imag_part;
ikptr_t    s_cn = ik_safe_alloc(pcb, compnum_size) | vector_tag;
IK_COMPNUM_TAG(s_cn) = compnum_tag;

pcb->root9 = &s_cn;
{
  IK_ASS(IK_COMPNUM_REAL(s_cn), \
     ika_integer_from_sword(pcb, rep));
  IK_SIGNAL_DIRT(pcb, IK_COMPNUM_REAL_PTR(s_cn));

  IK_ASS(IK_COMPNUM_IMAG(s_cn), \
     ika_integer_from_sword(pcb, imp));
  IK_SIGNAL_DIRT(pcb, IK_COMPNUM_IMAG_PTR(s_cn));
}
pcb->root9 = NULL;

To set or retrieve the real and imaginary parts we do:

ikptr_t  s_cn = the_compnum;
ikptr_t  s_re;
ikptr_t  s_im;

s_re = IK_COMPNUM_REAL(s_cn);
s_im = IK_COMPNUM_IMAG(s_cn);

IK_COMPNUM_REAL(s_cn) = s_re;
IK_SIGNAL_DIRT(pcb, IK_COMPNUM_REAL_PTR(s_cn));

IK_COMPNUM_IMAG(s_cn) = s_im;
IK_SIGNAL_DIRT(pcb, IK_COMPNUM_IMAG_PTR(s_cn));
Preprocessor Symbol: compnum_size

The number of bytes to allocate to hold a compnum memory block.

Preprocessor Symbol: compnum_tag

The tag of ikptr_t values used as first words in compnum memory blocks.

Preprocessor Symbol: disp_compnum_tag

Displacement of secondary tag word. The number of bytes to add to an untagged pointer to compnum to get the pointer to the first byte in the word holding the compnum tag.

Preprocessor Symbol: disp_compnum_real
Preprocessor Symbol: disp_compnum_imag

Displacements of real and imaginary parts. The number of bytes to add to an untagged pointer to compnum to get the pointer to the first byte of the reference to the real or imaginary part.

Preprocessor Symbol: off_compnum_tag

An integer to add to add to a tagged ikptr_t pointer to compnum to get the pointer to the first byte in the word holding the compnum tag.

Preprocessor Symbol: off_compnum_real
Preprocessor Symbol: off_compnum_imag

An integer to add to a tagged ikptr_t pointer to compnum to get the pointer to the first byte of the words referencing the real or imaginary part.

Convenience preprocessor macros

Preprocessor Macro: int IK_IS_COMPNUM (ikptr_t obj)

Return true if obj is a compnum object; otherwise return false.

Preprocessor Macro: ikptr_t IK_COMPNUM_TAG (ikptr_t X)

Evaluate to the location of the first word in the compnum memory block; X must be a tagged pointer referencing a compnum object. A use of this macro can appear both as operand and as left–side of an assignment.

Preprocessor Macro: ikptr_t IK_COMPNUM_REAL (ikptr_t X)
Preprocessor Macro: ikptr_t IK_COMPNUM_IMAG (ikptr_t X)
Preprocessor Macro: ikptr_t IK_COMPNUM_REP (ikptr_t X)
Preprocessor Macro: ikptr_t IK_COMPNUM_IMP (ikptr_t X)

Evaluate to the location of the real and imaginary parts in the compnum memory block; X must be a tagged pointer referencing a compnum object. A use of these macros can appear both as operand and as left–side of an assignment:

ikptr_t  s_cn = the_compnum;
ikptr_t  s_re;

s_re = IK_COMPNUM_REAL(s_cn);

IK_COMPNUM_REAL(s_cn) = s_re;
IK_SIGNAL_DIRT(pcb, s_cn);
Preprocessor Macro: ikptr_t * IK_COMPNUM_REAL_PTR (ikptr_t X)
Preprocessor Macro: ikptr_t * IK_COMPNUM_IMAG_PTR (ikptr_t X)
Preprocessor Macro: ikptr_t * IK_COMPNUM_REP_PTR (ikptr_t X)
Preprocessor Macro: ikptr_t * IK_COMPNUM_IMP_PTR (ikptr_t X)

Evaluate to a pointer to the real and imaginary parts in the compnum memory block; X must be a tagged pointer referencing a compnum object. These macros are useful in building the second argument for calls to ik_signal_dirt_in_page_of_pointer().

Operations on compnums

Function: int ik_is_compnum (ikptr_t obj)

Return true if obj is a compnum object.

Function: ikptr_t ika_compnum_alloc_no_init (ikpcb_t * pcb)

Allocate a new compnum object using ik_safe_alloc() and return a tagged reference to it. The fields are left uninitialised.

Function: ikptr_t ika_compnum_alloc_and_init (ikpcb_t * pcb)

Allocate a new compnum object using ik_safe_alloc() and return a tagged reference to it. Both the fields are set to the fixnum zero.


Next: , Previous: , Up: objects   [Index]