- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Dear Fortran experts,
I have found a rather strange behavior in one of our dlls generated with Intel Fortran compiler (Intel(R) Visual Fortran Compiler XE 14.0.0.103 [IA-32]). I have a routine in which the following code is written.
if (INDIC == 4 .or. INDIC == INDIC_ALL) CJOULE = -DHP*RCONST/CP
The variables DHP, RCONST and CP are of type real (double precison) and RCONST and CP are positive values. Some lines above, the following code is setting the value of DHP to zero.
DHP = 0.D0
When I look at the value of the variable CJOULE in the debugger it displays 0.0000000D+00, however in hexadecimal display it shows #80000000 meaning that the bit of sign is set to 1.
The dll is used into Excel through the COM layer and what I found is that in an previous version of the dll the value displayed in Excel was 0 and now Excel displays -0 ! The only changes I did between the two versions was simply to perform a rebuild instead of a simple build to generate the dll (the build was necessary because of a change in a source code which as nothing to do with the source code above).
Do you have any comment about that ?
Thanks and best regards.
Phil.
- Balises:
- Intel® Fortran Compiler
Lien copié
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Ifort used to require assume:minus0 to comply with f95 and later standards about signed zeros. Maybe it has changed.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
The debugger, as far as I know, doesn't display the sign for -0.Maybe Excel changed. /assume:minus0 has limited effect - primarily the SIGN intrinsic.and how formatted output is displayed. It has no effect on computations.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Hi,
Thanks for your answers.
What is surprising me is that the behavior has changed from one build to the next without changing the compiler version. I understand that -0 seems logical because of the minus sign in the expression but I don't understand the change in Excel display from one build of the dll to the next one.
Best regards,
Phil.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Maybe you have an uninitialized variable that is being referenced in the computation.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Do you mean one of the two other variables in the expression (RCONST or CP)?
Both are initialized: RCONST is the ratio of two array elements which contains constant values and CP is also a local variable which is calculated somwhere before the expression but in the same source code.
Phil.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
No idea - show us a complete program and we can say more.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
netphilou31 wrote:
.. -0 .. in Excel display ..
What exactly do you mean by -0. displayed in Excel? Is that in a cell in a workbook that got a value either from a user-defined function or filled by a Excel VBA operation that invoked a result which was ultimately determined in a Fortran DLL?
In all our experience, we have never seen Excel display a Fortran result of 0D0 in a cell, whether signed or not, as -0. when general formatting is in effect.
Are you sure the number returned is not a small, negative number (similar to -1.0D0*EPSILON(0D0)) that because of the particular selections of formatting in Excel (e.g., fixed format but with no decimal digits) is getting displayed as -0.?
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Hi,
I was afraid that you ask me this.
Unfortunately I can't because the calculation code is quite complex and depends also on other libraries. I could send you the source code of the subroutine showing this behavior but it contains more than 700 lines and it would require that I indicate to you the calculation path (input variables, values contained in the various common used, etc...).
Best regards,
Phil.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
To FortranFan,
I am sure that the value is equal to zero because of the fact that the variable DHP is assigned to zero with the expression DHP = 0.D0. Furthermore, in the debugger the value is displayed as 0.000000000D+00 and in hexadecimal display it shows #80000000. The Fortran code is embedded in a dll which is called by an ActiveX object in Excel (ActiveX object that offers additional calculation functions). The cell retrieving the value has a Standard formatting and it displays -0 if I do a special copy of the value into another cell by selecting only the value (and not the function) it also displays -0
Best regards;
Phil.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
netphilou31 wrote:
..in the debugger the value is displayed as 0.000000000D+00 and in hexadecimal display it shows #80000000. The Fortran code is embedded in a dll which is called by an ActiveX object in Excel (ActiveX object that offers additional calculation functions). The cell retrieving the value has a Standard formatting and it displays -0 if I do a special copy of the value into another cell by selecting only the value (and not the function) it also displays -0
..
Can you then not create a simple Fortran DLL with just a few lines of code that returns a hexadecimal #80000000 value which is called by a simple ActiveX object that just transfers the value back via a lines of VBA to an Excel cell and see if you get -0.? This could then be the "complete program" Steve asked for? Now if such a simple program doesn't show the same program, I'd lean toward a problem elsewhere in your actual code.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
FortranFan wrote:
Quote:
netphilou31 wrote:
..in the debugger the value is displayed as 0.000000000D+00 and in hexadecimal display it shows #80000000. The Fortran code is embedded in a dll which is called by an ActiveX object in Excel (ActiveX object that offers additional calculation functions). The cell retrieving the value has a Standard formatting and it displays -0 if I do a special copy of the value into another cell by selecting only the value (and not the function) it also displays -0
..
Can you then not create a simple Fortran DLL with just a few lines of code that returns a hexadecimal #80000000 value which is called by a simple ActiveX object that just transfers the value back via a lines of VBA to an Excel cell and see if you get -0.? This could then be the "complete program" Steve asked for? Now if such a simple program doesn't show the same program, I'd lean toward a problem elsewhere in your actual code.
I am afraid that this is not as simple as you say. I guess that this probably due to an internal problem in may code and I will try to analyze it in more details in order to find a possible explanation. If I can't, I may then decide to follow your request.
Best regards,
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
The problem as I see it is in
if (INDIC == 4 .or. INDIC == INDIC_ALL) CJOULE = -DHP*RCONST/CP
The "-' is an unary operation to be performed on the result of the remainder of the expression. Thus you get the -0.0.
Try using
if (INDIC == 4 .or. INDIC == INDIC_ALL) CJOULE = (-1.0_8)*DHP*RCONST/CP
With an optimization switch that respects ()'s
Jim Dempsey
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Hi Jim,
Thanks a lot for the advice. I have tried it but I do not probably use the right optimization switches.
What switch do you think I should use?
The actual command line switches are:
/nologo /debug:full /Od /fpp /DSIMULIS /DWIN32 /DFRENCH /DNEW_PURE /extend_source:132 /debug-parameters:all /warn:interfaces /Qsave /assume:byterecl /Qzero /fpe:1 /fp:source /fpconstant /Qfp-speculation=strict /iface:cvf /module:"Win32\Debug\\" /object:"Win32\Debug\\" /traceback /libs:static /threads /dbglibs /Qmkl:sequential /c
Best regards,
Phil,
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Jim,
I've also tried to change the calculation to:
if (INDIC == 4 .or. INDIC == INDIC_ALL) then CJOULE = -RCONST/CP CJOULE = DHP*CJOULE end if
and it does give the same result, i.e. -0 (same hexadecimal display in the debugger watch)
Best regards,
Phil.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
I think your safest bet would be:
if (INDIC == 4 .or. INDIC == INDIC_ALL) then IF(DHP == 0.0_8) THEN CJOULE = 0.0_8 ELSE CJOULE = -DHP*RCONST/CP ENDIF end if
While not clean (elegant), you can get on with your business.
This is a good example for why there should be an intrinsic to convert -0.0 to 0.0. You could write you own generic function that handles RELA(4), REAL(8) and REAL(16) types. A name like FIX_ZERO(x) might be appropriate. Then you could use
CJOULE = FIX_ZERO(-DHP*RCONST/CP)
In places were -0.0 induces problems.
Jim Dempsey
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
You ought to be able to write your own function. Simply add 0. (or tiny(x)*.5, or some such, if you are concerned with negative subnormals).
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Hi Jim,
That was a think I had in mind if the -0 was leading to problems.
I will keep your recomendation in my bookmarks to be able to find it easily in case I'll need it.
Best regards,
Phil.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Hi Phil,
While you are in there fixing -0.0 for interoperability issues with Excel, you might as well also enhance the FIX_ZERO function such that it becomes a FIX_FOR_EXCEL because (as Tim Prince is suggesting) you may have issues with not only -0.0, but sub-normal, the infinities, the QNAN and the SNAN. You might as well insert the do all fix in one edit pass. This will require you to find out what makes Excel Happy.
Note, this function can additionally write to an output file a log as to what edits it made to the original data. Then this file can be used to check anomalies that may occur in Excel
Jim Dempsey
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Hi Jim,
Thanks for the comment,
For the time being, I have rewritten the lines as follows:
if (INDIC == 4 .or. INDIC == INDIC_ALL) then if (DHP /= 0.D0) then CJOULE = -DHP*RCONST/CP else CJOULE = 0.D0 end if end if
Best regards,
Phil.

- S'abonner au fil RSS
- Marquer le sujet comme nouveau
- Marquer le sujet comme lu
- Placer ce Sujet en tête de liste pour l'utilisateur actuel
- Marquer
- S'abonner
- Page imprimable