Microsoft KB Archive/50899

{| = Excel 2.20: Using Floating Point Values in a Code Resource =
 * width="100%"|

Last reviewed: October 31, 1994

Article ID: Q50899

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 &quot;a&quot; 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 &quot;SetUpA4.h&quot;

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 &quot;pi&quot; in a file called &quot;trig&quot; would allow you to call the routine from Excel as follows: | A  -- 1 | =REGISTER(&quot;trig&quot;,&quot;pi&quot;,&quot;EBE&quot;) 2 | =CALL(A1,7.5,) 3 | =UNREGISTER(A1) 4 | =RETURN
 * }