diff --git a/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs b/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs index 63567c71f..6b3f438ac 100644 --- a/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs +++ b/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs @@ -359,6 +359,10 @@ namespace ICSharpCode.Decompiler.Disassembler } else if (operand is float) { float val = (float)operand; if (val == 0) { + if (1 / val == float.NegativeInfinity) { + // negative zero is a special case + writer.Write('-'); + } writer.Write("0.0"); } else if (float.IsInfinity(val) || float.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); @@ -375,6 +379,10 @@ namespace ICSharpCode.Decompiler.Disassembler } else if (operand is double) { double val = (double)operand; if (val == 0) { + if (1 / val == double.NegativeInfinity) { + // negative zero is a special case + writer.Write('-'); + } writer.Write("0.0"); } else if (double.IsInfinity(val) || double.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); diff --git a/ICSharpCode.Decompiler/Tests/DoubleConstants.cs b/ICSharpCode.Decompiler/Tests/DoubleConstants.cs new file mode 100644 index 000000000..940976f83 --- /dev/null +++ b/ICSharpCode.Decompiler/Tests/DoubleConstants.cs @@ -0,0 +1,28 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +public class DoubleConstants +{ + public const double Zero = 0.0; + public const double MinusZero = -0.0; + public const double NaN = double.NaN; + public const double PositiveInfinity = double.PositiveInfinity; + public const double NegativeInfinity = double.NegativeInfinity; +} diff --git a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj index 69598ac73..db8b70192 100644 --- a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj @@ -67,6 +67,7 @@ + diff --git a/ICSharpCode.Decompiler/Tests/TestRunner.cs b/ICSharpCode.Decompiler/Tests/TestRunner.cs index 009a3c6c1..14cf09593 100644 --- a/ICSharpCode.Decompiler/Tests/TestRunner.cs +++ b/ICSharpCode.Decompiler/Tests/TestRunner.cs @@ -88,6 +88,12 @@ namespace ICSharpCode.Decompiler.Tests TestFile(@"..\..\Tests\ControlFlow.cs", optimize: false, useDebug: true); } + [Test] + public void DoubleConstants() + { + TestFile(@"..\..\Tests\DoubleConstants.cs"); + } + [Test] public void IncrementDecrement() { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs index 665e15e71..2fd378017 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -1057,6 +1057,12 @@ namespace ICSharpCode.NRefactory.CSharp } return; } + if (f == 0 && 1 / f == double.NegativeInfinity) { + // negative zero is a special case + // (again, not a primitive expression, but it's better to handle + // the special case here than to do it in all code generators) + formatter.WriteToken("-"); + } formatter.WriteToken(f.ToString("R", NumberFormatInfo.InvariantInfo) + "f"); lastWritten = LastWritten.Other; } else if (val is double) { @@ -1075,6 +1081,12 @@ namespace ICSharpCode.NRefactory.CSharp } return; } + if (f == 0 && 1 / f == double.NegativeInfinity) { + // negative zero is a special case + // (again, not a primitive expression, but it's better to handle + // the special case here than to do it in all code generators) + formatter.WriteToken("-"); + } string number = f.ToString("R", NumberFormatInfo.InvariantInfo); if (number.IndexOf('.') < 0 && number.IndexOf('E') < 0) { number += ".0";