Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Signed zero values

netphilou31
Nouveau contributeur III
2 393 Visites

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.

0 Compliments
19 Réponses
TimP
Contributeur émérite III
2 393 Visites

Ifort used to require assume:minus0 to comply with f95 and later standards about signed zeros.  Maybe it has changed.

0 Compliments
Steven_L_Intel1
Employé
2 393 Visites

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.

0 Compliments
netphilou31
Nouveau contributeur III
2 393 Visites

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.

0 Compliments
Steven_L_Intel1
Employé
2 393 Visites

Maybe you have an uninitialized variable that is being referenced in the computation.

0 Compliments
netphilou31
Nouveau contributeur III
2 393 Visites

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.

 

0 Compliments
Steven_L_Intel1
Employé
2 393 Visites

No idea - show us a complete program and we can say more.

0 Compliments
FortranFan
Contributeur émérite III
2 393 Visites

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.?

0 Compliments
netphilou31
Nouveau contributeur III
2 393 Visites

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.

0 Compliments
netphilou31
Nouveau contributeur III
2 393 Visites

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.

0 Compliments
FortranFan
Contributeur émérite III
2 393 Visites

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.

0 Compliments
netphilou31
Nouveau contributeur III
2 393 Visites

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,

0 Compliments
jimdempseyatthecove
Contributeur émérite III
2 393 Visites

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

0 Compliments
netphilou31
Nouveau contributeur III
2 393 Visites

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,

0 Compliments
netphilou31
Nouveau contributeur III
2 393 Visites

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.

0 Compliments
jimdempseyatthecove
Contributeur émérite III
2 393 Visites

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

0 Compliments
TimP
Contributeur émérite III
2 393 Visites

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).

0 Compliments
netphilou31
Nouveau contributeur III
2 393 Visites

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.

0 Compliments
jimdempseyatthecove
Contributeur émérite III
2 393 Visites

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

0 Compliments
netphilou31
Nouveau contributeur III
2 393 Visites

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.

0 Compliments
Répondre