Yes, I don't know if it's reasonable, either - but it does appear to be reliable except when a pre-VC8 MS Compiler is being used.
You may find that reliability short-lived. I'm with ELISHEVA. The two formal ways of comparing floats/doubles are (coded in Perl, but same idea):
# absolute error method
$is_within_tolerance = abs($value - $expected) < EPSILON;
# relative error method - $tolerance_error should be within threshold
+percentage
$tolerance_error = abs(($value - $expected) / $expected);
Crazy suggestion: You could write a function redofloat() that sprintf "%.15f" the number and then converts the resulting string back to a float/double. The idea here is to truncate each number's least significant bits that differ, caused by the division operations. Faster, if you can mask those bits off directly (but then you'd have to worry about portability).
Then: redofloat(foo) == redofloat(nv) | [reply] [d/l] [select] |
You may find that reliability short-lived.
Could be - I find in Kernighan & Ritchie:
"When double is converted to float, whether the value is rounded or truncated is implementation-dependent."
That would appear to open the door to the possibility that we *can* do float f = X; double d = X; and still have f != (float)d (for some value/expression X).
The two formal ways of comparing floats/doubles are ...
Yes, and those are good ways - but I'm looking at comparing a float and a double that have been assigned the same value/expression.
Still, now that I've found that statement in K & R, I'll see if anyone on the PDL list sees any cause for concern. My hunch is that the current method will stand until someone reports a breakage. I guess I could report a breakage on the basis of my experience with VC 7.0, but that breakage was just straight out compiler flakiness - nothing to do with the "implementation-dependent" behaviour alluded to by K & R.
Cheers, Rob
UPDATE: I think the way PDL is handling these values is fine. Afaict, pdl(float, 2/3) will assign exactly the same value as used by setvaltobad(2/3) In both cases the value is (double)2/3 cast to a float, so behaviour will be as desired, irrespective of the way the compiler implements the cast from double to float.
| [reply] [d/l] [select] |