Strange float rounding in String::Format()

G

Guest

Hi all,

I am trying to port some old code which uses the old C-style formatting
functions (eg. fprintf etc) to Visual C++ .Net 2005 (SP1) and have run into
some problems with the output of floating point numbers.

I have compared the output of the old and new systems and have found that
the last digit of the float is different. For an example - I have a float
variable which comes into my program over a serial connection from another
system. I then print this out using String::Format() with a format string of
"{0,13:E5}" which, I understand, should print it with a width of 13
characters, in scientific notation format, with 5 digits after the decimal
point.

It seems to do that, but the problem I am finding is that the last of those
digits is different to the last digit in the old system. An example of this
is that for one situation, the old system produces a value of 5.02776E-005
and the new system produces a value of 5.02777E-005. I have taken the binary
value which is being given to the systems and have converted it to a float
using the IEEE 754 standard and it comes out as
5.0277645641472190618515014648438E-5 (this calculation was performed using
Windows Calculator and mental arithmetic, so should not be affected by the
language I am using). Looking at the 'actual' value and the values the two
systems are producing, it seems that the value produced by the current system
is 'wrong'. It seems to be rounding up the 6 to a 7, even though the six is
followed by a 4 - which should mean it doesn't round up!

Does anyone know why this is happening? And, more importantly, what we can
do about it? It is important that we get the same results as the old system
for compability with other systems which will be using the output data.

Thanks,

Robin
 
J

Jon Skeet [C# MVP]

It seems to do that, but the problem I am finding is that the last of those
digits is different to the last digit in the old system. An example of this
is that for one situation, the old system produces a value of 5.02776E-005
and the new system produces a value of 5.02777E-005.

Hmm.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

<snip>
 
G

Guest

Jon,

Thank you for your prompt reply. Your article on how to write a short but
complete program was very useful. I believe the following program illustrates
my problem.

using namespace System;

int main(array<System::String ^> ^args)
{
float Test = 5.02776456e-5;

Console::WriteLine(Test.ToString("E8"));
Console::WriteLine(Test.ToString("E5"));

Console::ReadKey();

return 0;
}

The output I expect to get is:

5.02776456E-005
5.02776E-005

The output I actually get is:

5.02776456E-005
5.02777E-005

I hope this explains the problem sufficiently.

Kind Regards,

Robin
 
J

Jon Skeet [C# MVP]

robintw said:
Thank you for your prompt reply. Your article on how to write a short but
complete program was very useful. I believe the following program illustrates
my problem.

It certainly does. Interesting. Yup, it looks like a bug to me too.

I suggest you report it at connect.microsoft.com...
 
G

Guest

Jon,

Thank you very much. I have now reported it as a bug, and hopefully will get
a response with a workaround or a fix relatively soon, as this will cause
problems with implementing our software.

Thanks again,

Robin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top