Re: [GD-General] FLT_MIN
Brought to you by:
vexxed72
|
From: Pierre T. <p.t...@wa...> - 2003-01-03 17:40:20
|
> Thus, if you allow for denormalized
> numbers,
Ok, I found this in the MSDN :
_control87( _EM_INVALID, _MCW_EM ); // DENORMAL is unmasked by this call
If I use this, an FPU exception is generated on underflow, and resulting
values are different indeed. Ok, it makes sense now - I just never really
bothered thinking about denormalized values before.
However I'm surprised the default state is not to trigger the exception. As
long as it works well, I think I'm going to allow denormalized numbers. Any
known problems with this ?
------------------
For the records, the whole thing started when a function similar to that one
failed in Debug :
void MyVector::ClampLength(float limit_length)
{
float CurrentSquareLength;
if((CurrentSquareLength = SquareLength()) > limit_length * limit_length)
{
float Coeff = limit_length / sqrtf(CurrentSquareLength);
x *= Coeff;
y *= Coeff;
z *= Coeff;
}
}
( With of course:
float MyVector::SquareLength() const { return x*x + y*y + z*z; }
)
Fed with this, it bypasses the test and divides by zero anyway :
const float MaxLength = 4.91523e-24f;
MyVector Dummy(-1.11408e-23f, -4.0593e-24f, 5.51083e-25f);
Dummy.ClampLength2(MaxLength);
That's a very subtle (and interesting IMHO) bug that happens only because of
a combination of bad things :
- limit_length squared underflows to zero
- SquaredLength is ~10e-46 so it should underflow as well, and the test
should become "if( 0 > 0 )" => false => no divide. Yet it doesn't underflow
since internally the computation is performed with double-precision,
regardless of the code using "float" or "double". So it really does "if
(10e-46 > 0)" => true => blam.
- the way the function is written, doing the assignment in the "if" (it
wouldn't break if it was done when declaring the float, because the 10e-46
would have been assigned to the float, becoming zero)
For some reasons it works correctly in Release. Probably just an
accident....
Pierre
|