View Single Post
  #13   Report Post  
Posted to microsoft.public.excel,microsoft.public.excel.programming
Lynn McGuire[_2_] Lynn McGuire[_2_] is offline
external usenet poster
 
Posts: 47
Default Excel and the Math Coprocessor for DLLs

On 3/21/2012 5:40 PM, joeu2004 wrote:
"Lynn McGuire" wrote:
Bummer, neither of
_control87( _PC_64+_RC_NEAR, _MCW_PC+_MCW_RC);
_control87 (_PC_64, _MCW_PC);
did not help. Something is really weird here.


The only "really weird" thing here is that apparently you are not comprehending my explanations. My bad: TMI!

The outcome with _control87 should come as no surprise because I already demonstrated that no change in the rouned 64-bit value would
result in exactly zero.

I concluded, therefore, that it is the extended 80-bit precision that, by coincidence, causes that particular example to become zero.

I say "by coincidence" because the 80-bit precision will not always cause expressions of the form (x/y)*y-x to be zero, for integer x
and y, just as there are integer x and y where that expression is not zero using 64-bit precision.

I never fully explained my reference to "80-bit precision". Perhaps you are unaware....

Although type Double is represented in memory by 64-bit floating-point, Intel CPUs use 80-bit floating-point registers to perform
arithmetic.

Since the 80-bit FP registers are accessible to the CPU, compilers can take advantage of them to store pairwise intermediate results.

For example, the compiler might put x into FP1 and y into FP2, compute FP1/FP2 in FP3 (x/y), then compute FP3*FP2 ((x/y)*y) in FP3,
and finally compute FP3-FP1 in FP3 ((x/y)*y-x). Finally, FP3 would be rounded to 64-bit and stored into a variable, chptst in your case.

That is what is happening in my VBA example procedure called testit2().

-----

As for why the C++ compiler might optimize the DLL when linked to a C++ application, but not when linked to an Excel/VBA application,
both Martin and I conjectured that that is simply how things work.

Perhaps someone who understands Microsoft C++ and DLLs better can offer a more detailed factual explanation. I don't think we need
any more wild speculation ;-).


Yes, I comprehended your explanation. And I understand the
difference between 64 bit precision and 80 bit precision -
that is what the _PC_64 flag is for. I started programming
using 36 bit words for single precision (univac 1108). I've
been down this road before unfortunately.

BTW, I never said that my DLL was written in Visual C++.
My DLL is written in 700K lines of Fortran, C and C++ code.
But that is all built at compile and link time. The only
thing that can be a difference here is how the math
coprocessor is running.

I am currently intrigued by this conversation:
http://windowssecrets.com/forums/sho...8VB-Fortran%29
"We finally solved the problem. What happened is the floating
point control of windows is set by each language according to
its own set of parameters. This affects how the math processor
rounds numbers and other various operations. C and Fortran
sets the floating point parameters equally, VB and VBA each
have their own set of parameters. We had to write a bit of
Assembly code to force C, Fortran, VB, and VBA to use the same
parameters for the floating point control. Now all four
languages now give the same answers. This was a doosie that
took 4 days to solve."

I wish that they had posted the code, it sounds very
interesting.

Thanks,
Lynn