"negative zero" behavior between C++ and C# code is different - by Paul Porta

Status : 

  Postponed<br /><br />
		Due to current priorities, the product team decided to postpone the resolution of this item.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.


0
0
Sign in
to vote
ID 344366 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 5/15/2008 1:52:36 PM
Access Restriction Public

Description

The following code compiled as a CPP file in a new "Empty Project" under a C++ General Project will generate different results on the two sprintf function calls.  

The first sprintf has a result of "-0.000000" 
The second sprintf has the proper result: "0.000000".

#include "stdio.h"

void main()
{
	double dZero, dNegativeOne, dResult;
	char szTemp[20];

	dZero =  0.0;
	dNegativeOne = -1.0;
	dResult = dZero;

	dResult =  (dResult * dNegativeOne);
	sprintf(szTemp, "%f", dResult);
	szTemp[0] = 0;

	dResult =  (dResult * dNegativeOne) + (double)(0.0);
	sprintf(szTemp, "%f", dResult);
	szTemp[0] = 0;
}

and a similar application written in C# generates different results...

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            double dZero, dNegativeOne, dResult;
            string szTemp;

            dZero =  0.0;
            dNegativeOne = -1.0;
            dResult = dZero;

            dResult = (dResult * dNegativeOne);
            szTemp = dResult.ToString();
            szTemp = "";

            dResult = (dResult * dNegativeOne) + (double)(0.0);
            szTemp = dResult.ToString();
            szTemp = "";
        }
    }
}

Notice that the C# application does not have the problem with the "negative zero" and produces the proper results.

Here are the versions that are installed on my system:
Microsoft Visual Studio 2005 Version 8.0.50727.762  (SP.050727-7600)
Microsoft .NET Framework Version 2.0.50727
Installed Edition: Professional
Microsoft Visual C# 2005   77626-009-0000007-41214
Microsoft Visual C++ 2005   77626-009-0000007-41214
using Microsoft Visual Studio 2005 Professional Edition - ENU Service Pack 1 (KB926601)   


see attached bitmaps for screen shots of the debugging sessions...
Sign in to post a comment.
Posted by Paul Porta on 9/2/2008 at 6:18 AM
I still believe that the C# results are correct.
I still believe that the C++ results are wrong.

The "negative zero" result in C++ is not reasonable, especially when I adding a 0.0 value gets the proper result.

I will repeat my comments from 5/16/2008 at 10:20am because this question has not been answered:

Are there any compiler/linker options I can use to get rid of the "negative zero" result?

My users don't want to see "negative zero" on reports or screen displays (when the double is displayed on the screen it must be converted to a string, etc)

Adding a "positive zero" to each double before it is displayed seems like a workaround that should be fixed at the compiler/linker level instead of in a developer's code.

Posted by Microsoft on 8/28/2008 at 5:30 PM
Hi,

This is also By Design form the C# perspective. If you disagree with any of this By Design let us know.

Thanks!
Marcelo Guerra
C# Compiler QA
Posted by Paul Porta on 5/16/2008 at 1:01 PM
Please see the comment I made below in the community discussion area.

Posted by Paul Porta on 5/16/2008 at 10:20 AM
I believe that there might be an additional problem in the C++ code listed above. Adding a "positive zero" to anything should not change a result.

dResult = (dResult * dNegativeOne);

should be equalivalent to

dResult = (dResult * dNegativeOne) + (double)(0.0);

The "negative zero" value of (0x8000000000000000) when added to the "positive zero" value of (0x0000000000000000) should result in a "negative zero"?

Are there any compiler/linker options I can use to get rid of the "negative zero" result?

My users don't want to see "negative zero" on reports or screen displays (when the double is displayed on the screen it must be converted to a string, etc)

Adding a "positive zero" to each double before it is displayed seems like a workaround that should be fixed at the compiler/linker level instead of in a developer's code.


Posted by Jonathan [MSFT] on 5/16/2008 at 9:37 AM
Hi: having taken a look at this I am convinced that from a C++ prespective this is By-Design. The problematic line is:

    dResult = (dResult * dNegativeOne);

Within this statement dResult is initially positive zero (0x0000000000000000) and dNegativeOne is -1.0 (0xBFF0000000000000) so as positive * negative => negative - negative zero (0x8000000000000000) is the correct result.

So it looks like the bug is in the C# compiler. In fact the 3.0 version of the C# Standard has a table in 7.7.1 that shows that a positive zero * a negative number should produce negative zero.

I will move his bug report over to the C# team.

Jonathan Caves
Visual C++ Compiler Team
Posted by Microsoft on 5/15/2008 at 9:31 PM
Thanks for your feedback. We are escalating this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Thank you,
Visual Studio Product Team