When is a double a string
-
Luc Pattyn wrote:
log("i="+i+" b="+b+" a="+a+"="+a.ToString("E30")+" s="+s);
It generates this output:
i=48 b=3.5527136788005E-15 c=1=1.000000000000003600000000000000E+000 s=1
That's clever, you put in the letter a and it prints out the letter c. :)
Yeah, I switched a and c to better resemble the OP; and of course I forgot one instance. I'll fix it! BTW: you don't want to know what else my log() method is capable of... :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
-
While that code looks ludicrous and is hiding its probable intent very well, it does make some sense, although I would prefer to tackle the issue differently. He probably is looking for values of A that are either one, or pretty close to one, so close that the default numeric format just shows "1". Here is a little test illustrating that:
double c=1;
double b=1;
for (int i=0; i<1000; i++) {
double a=c+b;
string s=a.ToString();
if (s=="1") {
log("i="+i+" b="+b+" a="+a+"="+a.ToString("E30")+" s="+s);
break;
}
b=b/2;
}It generates this output:
i=48 b=3.5527136788005E-15 a=1=1.000000000000003600000000000000E+000 s=1
It is always risky to use equality tests on floating-point numbers. The normal approach would be something along these lines:
if ( Math.Abs(a-1) < epsilon ) ...
where epsilon would be a small positive constant, say 1.0E-15 :) [EDIT] fixed a little a/c confusion [/EDIT]
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
modified on Thursday, May 13, 2010 10:50 AM
-
Luc Pattyn wrote:
where epsilon would be a small positive constant, say 1.0E-15
Or even
Double.Epsilon
- thats why it's there.I don't think so; MSDN says "The value of this constant is 4.94065645841247e-324.", as it is the smallest non-zero value a double can hold. However what the OP probably needed is the smallest value you can add to one to make it different from one (that is about 1.E-15), or even a multiple thereof, as testing against the smallest possible value would be risky itself, as a lot of floating-point operations aren't accurate up to the last bit. IMO they should not have called their value Epsilon. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
-
While that code looks ludicrous and is hiding its probable intent very well, it does make some sense, although I would prefer to tackle the issue differently. He probably is looking for values of A that are either one, or pretty close to one, so close that the default numeric format just shows "1". Here is a little test illustrating that:
double c=1;
double b=1;
for (int i=0; i<1000; i++) {
double a=c+b;
string s=a.ToString();
if (s=="1") {
log("i="+i+" b="+b+" a="+a+"="+a.ToString("E30")+" s="+s);
break;
}
b=b/2;
}It generates this output:
i=48 b=3.5527136788005E-15 a=1=1.000000000000003600000000000000E+000 s=1
It is always risky to use equality tests on floating-point numbers. The normal approach would be something along these lines:
if ( Math.Abs(a-1) < epsilon ) ...
where epsilon would be a small positive constant, say 1.0E-15 :) [EDIT] fixed a little a/c confusion [/EDIT]
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
modified on Thursday, May 13, 2010 10:50 AM
Luc Pattyn wrote:
where epsilon would be a small positive constant, say 1.0E-15
You can't reliably use a constant for comparisons. The value of epsilon has to be related to the magnitude of the numbers involved. For example (VC++ 6 compiler for reference)
double d1 = 1e299; double d2 = 1e299 - 1; double diff = d1 - d2;
gives a result with diff being zero, not one.
double d1 = 1e10; double d2 = 1e10 - 1; double diff = d1 - d;
gives a result with diff being 1, as expected. Basically, epsilion has to be larger than the minimum precision of the double data type given the values contained in it, and the precision, as an absolute, varies with the values.
-
Luc Pattyn wrote:
where epsilon would be a small positive constant, say 1.0E-15
You can't reliably use a constant for comparisons. The value of epsilon has to be related to the magnitude of the numbers involved. For example (VC++ 6 compiler for reference)
double d1 = 1e299; double d2 = 1e299 - 1; double diff = d1 - d2;
gives a result with diff being zero, not one.
double d1 = 1e10; double d2 = 1e10 - 1; double diff = d1 - d;
gives a result with diff being 1, as expected. Basically, epsilion has to be larger than the minimum precision of the double data type given the values contained in it, and the precision, as an absolute, varies with the values.
that is elementary. the example was about a value of 1, that is why 1.E-15 was appropriate. In general, for a non-zero positive target value, one would typically use:
if (Math.Abs(currentValue-targetValue) < targetValue*epsilon) ...
:)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
-
that is elementary. the example was about a value of 1, that is why 1.E-15 was appropriate. In general, for a non-zero positive target value, one would typically use:
if (Math.Abs(currentValue-targetValue) < targetValue*epsilon) ...
:)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
It might be obvious to you, but the "absolute value of difference less than very small constant" idiom is very common, and leads to some really hard to find bugs. I only mentioned it because your original post used the constant, and the more that gets published, the more the bug hets promuglated in code all over the place. You even see it in CS academic texts, which is really concerning.
-
double A;
A = ...some calculations...
if (A == 1 || String.Compare(A.ToString(), "1") == 0)At what point does A become a string and needs a string comparison :wtf:
I know the language. I've read a book. - _Madmatt
That code makes me sad :(
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
-
that is elementary. the example was about a value of 1, that is why 1.E-15 was appropriate. In general, for a non-zero positive target value, one would typically use:
if (Math.Abs(currentValue-targetValue) < targetValue*epsilon) ...
:)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
Luc Pattyn wrote:
In general, for a non-zero positive target value, one would typically use:
The minimum amount of error one should accept would depend not on the target value, but upon the magnitude of the largest value from which something was subtracted to yield the target value. For example, when subtracting 281474976710655.1 from 281474976710656.1, the final result will be about 1.03125 which is much larger than a typical 'epsilon' one would expect for a number around one. The real question, of course, should be how close does the number need to be to be identical from a 'practical' perspective. That's going to depend entirely on the application. If one is trying to produce a list of boards one needs to cut, and two boards differ by 0.1", that may or may not be a difference worthy of producing a separate line item. If boards have to fit within 0.05", the 0.1" difference would be significant. If the boards are going to have some mounting slop, even a 0.5" difference might be insignificant. Obviously the computer isn't going to magically know what's meaningful and what isn't.
-
Mark Nischalke wrote:
if(A == 1 || A == 2 || A == 3)
Damn C# compiler. A clever C novice would write:
if(A == 1 || 2 || 3) ...
which C# does not like. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
but COBOL does. +1 COBOL. you can also do multiple assignments : set A to B,C,D +2 COBOL. which brings COBOL up to a score of -32.
-
but COBOL does. +1 COBOL. you can also do multiple assignments : set A to B,C,D +2 COBOL. which brings COBOL up to a score of -32.
Great. What is keeping you from using it? there are a couple of .NET Cobol compilers. Fujitsu has one, ... and CP could sure use some Cobol articles. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
-
Great. What is keeping you from using it? there are a couple of .NET Cobol compilers. Fujitsu has one, ... and CP could sure use some Cobol articles. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
Luc Pattyn wrote:
What is keeping you from using it?
who said i wanted to ?
-
but COBOL does. +1 COBOL. you can also do multiple assignments : set A to B,C,D +2 COBOL. which brings COBOL up to a score of -32.
In Pascal, one could code:
If (A in [1,2,3]) Then
.. do somethingThe time and space efficiency of doing that varies considerably by compiler, though. Incidentally, Pascal has variables of type "Set of (whatever)" and includes operations to compute intersection, union, test for inclusion or subset, etc.