SUMMARY
When creating a code resource to be called from Excel 2.20, steps
should be taken to ensure correct manipulation of floating point
values.
Many compilers, such as Think's Lightspeed C, treat typed floating
point values as string constants. To correctly execute floating point
manipulations, the following three steps must be taken:
- Any typed floating point values must be cast as an 8-byte double
(for example, short double in Lightspeed C).
For example, in Lightspeed C, to find the product of a floating
point value pointed to by "a" and the number 2.5, you could use the
following code segment:
*b = *a * (short double) 2.5;
- The A4 address must be adjusted to ensure the values are returned
from the correct memory location.
Because the code is compiled as a resource rather than a program
segment, values are manipulated in Excel's memory addresses rather
than the code's own addresses. Because of this, the addresses for
the code resource must be adjusted to comply with Excel's
addresses.
In Lightspeed C, this can be done using predefined macros from
SetUpA4.h, as follows:
a. Insert the following as a declaration at the beginning of your
code segment to include Lightspeed C's Setup macro library:
#include "SetUpA4.h"
b. As the first two lines of your executable code, insert the
following:
RememberA0();
SetUpA4();
c. As the last line of executable code before the return statement,
enter the following:
RestoreA4();
You can also do this without using existing macros by using the
following method:
a. Declare a long variable for temporarily storing A4:
Long A4Sav;
b. In the first two lines of executable code, swap addresses by
inserting the following:
asm {move.l a4, A4Sav};
asm {move.l a0, a4};
c. Restore the contents of A4 in the last line of executable code
before the return statement by entering the following:
asm {move.l A4Sav, a4};
- The return value must be specified as its own variable.
In the case of floating point numbers, the return value must always be
specified as its own variable within the code resource. You cannot
return the variable assigned as a pointer to one of the passed
addresses because Excel clears those addresses when the value is
returned. This is done to free memory taken by the passed parameters.
Thus, a code resource that passes three values and returns a pointer
to a floating point value would have a minimum of four variables
defined (one for each passed to the code resource, and a fourth for
the value returned to Excel).
A sample code segment to multiply a passed value by 9 would be as
follows:
pascal short double *main(a,b)
short double *a, *b;
{
long A4Sav;
asm {move.l a4, A4Sav};
asm {move.l a0, a4};
*b = *a * (short double) 3.141592654;
asm {move.l A4Sav, a4};
return (b);
}
Naming the resource "pi" in a file called "trig" would allow you to
call the routine from Excel as follows:
| A
----------------------------------
1 | =REGISTER("trig","pi","EBE")
2 | =CALL(A1,7.5,)
3 | =UNREGISTER(A1)
4 | =RETURN()
|