Next: objects cflonums, Previous: objects flonums, Up: objects [Index]
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
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));
The number of bytes to allocate to hold a compnum memory block.
The tag of ikptr_t
values used as first words in compnum memory blocks.
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.
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.
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.
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.
Return true if obj is a compnum object; otherwise return false.
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.
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);
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()
.
Return true if obj is a compnum object.
Allocate a new compnum object using ik_safe_alloc()
and return a
tagged reference to it. The fields are left uninitialised.
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: objects cflonums, Previous: objects flonums, Up: objects [Index]