On 1 Jun 2005 00:51:38 -0500, Anton Noll <> wrote
in comp.lang.c++:
> We are using Visual Studio 2003.NET (C++) for the development
> of our software in the fields digital signal processing and
> numerical acoustics.
>
> One of our programs was working correctly if we are using the
> Debug-Version of the program, but it fails (or leads to false
> results) if we are using the Release-Version. After a long
> debugging session we found out, that our program was working
> correctly, but the floating point processing (accuracy) of the
> Debug-Version and the Release-Version is different and leads to
> different numerical results.
If you are concerned with accuracy, why the heck are you using the
type float, which by its very nature has a limited accuracy?
And for that matter, why are you using any version of Visual C++? Use
a compiler that provides the full hardware precision of the FPU for
long double, instead of throwing it away for marketing reasons? Try
using gcc for Windows (the cygwin port, not mingw). Or Borland, or
any other compiler that does not throw away 16 bits of precision.
And looking through your code sample, I see a large number of
constants scattered through it, a very bad coding practice. These
should be defined as const values with meaningful names. But the most
important thing is that none of them has more than four significant
digits, even though the limited format you are using provides for six
significant decimal digits. Why not improve the accuracy of your
calculations by improving the accuracy of your constants?
On the other hand, why not just build your programs in debug mode, if
it gives you the result you want and you don't want to use a better
compiler for numerics, or even the most accurate floating point type
that your compiler provides?
Do you understand the limitations and compromises of floating point
arithmetic, especially using the very low precision Intel single
precision type? See this standard reference on the subject:
http://docs.sun.com/db/doc/800-7895/6hos0aou4
> This bug occurs independend of the optimization level which is
> used for the Release-Version (even if optimization is disabled).
The question I have is, what do you expect anyone in this group to do
for you? We can't fix Microsoft's compiler, if indeed it is broken.
Is there anything you expect to read here that can be of any use to
you other than telling you to use double for more precision or switch
to a different compiler?
The actual cause of the difference you see is most likely a difference
in the way some intermediate values are handled. Most likely in the
release version, more intermediate values are kept in FPU registers as
64-bit doubles instead of being truncated to 32 bits and stored to
memory.
> We have dedected this bug only in the C++ compiler of Visual
What proof do you have that this is a bug?
> Studio 2003.NET. With Visual Studio 6 both versions of our
> program are working (with the same results).
>
> I have included a test program in this mail. If the program
> below is compiled with Visual Studio 2003.NET the output of
> the Debug- and the Release-Version is differnt.
>
> Note: There is also a problem with casting floats to int. This
> means, in some cases the result of "(int)x" in the Debug- and
> the Release-Vesion is not the same.
Do you understand these two things:
1. Casting a floating point value to int is not necessary and a
completely useless waste of typing? Assigning a floating point value
to an int does the conversion automatically, no cast required. If the
integral part of the float value is outside the range of int, you get
the same undefined behavior whether you use the cast or not?
2. Assignment of a floating point value to an integer type, with or
without a cast, is a truncating operation. It does not round. So if
you have a value that after having passed through several operations
is equal to 2.999999999, it will convert to the integer value 2, but
if you have 3.000000001, it will convert to the integer value 3?
> I have tried to report this bug/problem to the microsoft company,
> but after visiting a lot of web-pages without any chance to send
> a note to microsoft i gave up.
Try asking in one of Microsoft's support groups in the
news:microsoft.public.* family, on the server msnews.microsoft.com.
Someone there can tell you how to file a report with Microsoft.
> Anton Noll
> Austrian Academy of Sciences, Acoustics Research Institut
> 1010 Vienna, Reichsratstrasse 17, Austria
> E-Mail:
>
>
> Test program (a part of a fir filter development algorithm)
>
> ----- BEGIN OF NUMTEST.CPP -----
> // numtest.cpp : Defines the entry point for the console application.
> //
>
> #include "stdafx.h"
> #include <stdio.h>
> #include <stdlib.h>
> #include <math.h>
> #include <float.h>
>
> static float _dfunci0(float x)
> {
> float sa, uh, u=1, s=1;
From a C++ point of view, or in fact from just about any programming
language, this program is terrible. Variable names like 'sa', 'uh',
'u', and 's' are inexcusable. Are you aware that using more
characters in the names of the variables does not make the program
larger or slower, and does not change the output?
> int i = 1;
> while(true)
> {
> sa = s;
> uh = x / 2 / (float)i++;
> u = u * uh * uh;
> s = s + u;
> if(sa == s) return s;
Please read a decent reference on floating point math in computer
programs. Especially what it has to say on comparing floating point
values for exact equality. For some values of 'x', this function will
never return.
> }
> }
>
> int _tmain(int argc, _TCHAR* argv[])
> {
> float delta = (float)1e-6, freq = (float)1;
> float fe = (float)0.05, fg = (float)0.1;
Are you aware that numbers like 0.05 and 0.1 cannot be represented
exactly in binary floating point representation?
> int k, n;
> float pi, a, df, fs, alpha, wn, hilf;
> float *cw, *w,*c;
>
> pi = (float)atan2((float)0,(float)-1);
> a = (float)(-20 * log10(delta));
> df = (fg-fe) / freq;
> fs = (fg+fe) / 2 / freq;
> n = int((a - 7.95) / 28.72 / df) + 1;
>
> cw = new float[n+1];
> c = new float[n+1];
> w = new float[n+1];
>
> if(a > 50)
> alpha = (float)(0.1102 * (a-8.7));
> else if(a > 21)
> alpha = (float)(pow(0.5842*(a-21),0.4) + 0.07886*(a-21));
> else
> alpha = 0;
>
> c[0] = 2*fs;
> for(k = 1;k <= n; k++)
> c[k] = sin(2 * pi * k * fs) / (pi * k);
>
> wn = _dfunci0(alpha);
> for(k = 0;k <= n; k++)
> {
> hilf = (float)1 - (float)(k*k) / (float)(n*n);
> if(hilf <= 0)
> hilf = 0;
> else
> hilf = alpha * sqrt(hilf);
> w[k] = _dfunci0(hilf) / wn;
> }
>
> for(k = 0; k <= n; k++)
> cw[k] = (float)(c[k] * w[k]);
>
> FILE *test = fopen("numtest.txt","wt");
> for(k = 0; k <= n; k++)
> fprintf(test,"%g,%g,%g\n", c[k], w[k], cw[k]);
> fclose(test);
>
> return 0;
> }
> ----- END OF NUMTEST.CPP -----
--
Jack Klein
Home:
http://JK-Technology.Com
FAQs for
comp.lang.c
http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++
http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html