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 |