Float consistency

  • Thread starter Thread starter David W
  • Start date Start date
D

David W

Hello,

float nanometers(long pm)
{
return pm / 1000.0f;
}

void f()
{
if(nanometers(309311L) == nanometers(309311L))
{
// do something
}
}

Is there any way to force the VS .NET 2003 C++ compiler to produce a result of true for the 'if'
expression above? I get false even with the /Op switch. The original code from which I created the
example produced true on an earlier compiler (1.52c). The project is large and I don't know how many
similar problems are lurking in it and there's no easy way to look for them.

DW
 
David W said:
Hello,

float nanometers(long pm)
{
return pm / 1000.0f;
}

void f()
{
if(nanometers(309311L) == nanometers(309311L))
{
// do something
}
}

Is there any way to force the VS .NET 2003 C++ compiler to produce a
result of true for the 'if'
expression above? I get false even with the /Op switch. The original code
from which I created the
example produced true on an earlier compiler (1.52c). The project is large
and I don't know how many
similar problems are lurking in it and there's no easy way to look for
them.

DW

The best advise is to upgrade to VS 2005 which doesn't exhibit this problem.
The VS 2003 C++ compiler is storing the intermediate float number in a dword
space in memory, but when it reloads it back into the floating point
register, there is extra garbage in the low order bits since the FP register
is much wider than the dword. VS 2005 C++ compiler gets around this by
storing the intermediate values in a qword memory space.

Having said this, this is still somewhat dangerous code to use. Checking for
equality between floating pointer numbers is frought with danger because of
implicit numerical roundoff when fractions are computed within the FP
registers and truncated to fit the register.

HTH

Brian
 
Brian Muth said:
The best advise is to upgrade to VS 2005 which doesn't exhibit this
problem.

Quite an expensive fix, not to mention the time involved in getting a large
project rebuilt with a new compiler. No 2003 service pack that fixes it? If
there isn't there should be, given the outlay.
The VS 2003 C++ compiler is storing the intermediate float number in a dword
space in memory, but when it reloads it back into the floating point
register, there is extra garbage in the low order bits since the FP register
is much wider than the dword. VS 2005 C++ compiler gets around this by
storing the intermediate values in a qword memory space.

Having said this, this is still somewhat dangerous code to use. Checking for
equality between floating pointer numbers is frought with danger because of
implicit numerical roundoff when fractions are computed within the FP
registers and truncated to fit the register.

Yes, I'm aware of the danger, but, intuitively, you would expect identical
starting values and identical operations to produce identical results, even
in floats. In the real program the calculation is more involved, but the
inputs are longs and ints, not floats.

David
 
David said:
Quite an expensive fix, not to mention the time involved in getting a
large project rebuilt with a new compiler. No 2003 service pack that
fixes it? If there isn't there should be, given the outlay.

Service pack 1 for VS2003 was recently released [1]. Have you tried it?

If it doesn't fix the problem, your only other option is to call Product
Support to see if there's a hotfix available.

[1] http://support.microsoft.com/?kbid=918007

-cd
 
Back
Top