[ODE] What is the ODE approach to denormals?

Jon Watte hplus-ode at mindcontrol.org
Mon Apr 26 18:23:44 MST 2004


I dare you to show me one machine except for the playstation series 
where "float" does not have 8 bits of exponent, and "double" does 
not have 11 bits of exponent. Actually, playstation has floats, but 
not denormals as we know them, so it's even more important to avoid 
them.

I'm fine with using a #define for the constants that I hard-coded 
here, but the names become quite confusing. Something like:

dRealDenormalEpsilon  // this is about the smallest representable 
                      // number that won't go denormal
dRealDenormalEpsilonSqrt  // this is about the smallest number 
                          // which won't go denormal when squared

There are no standard header values that you can use, so we have 
to hard-code our own -- the ones I chose are good first 
approximations. I explicitly don't want to go down the route of 
defining the actual smallest value, as you'd typically have to do 
that by loading a hex constant into memory, with all its byte order 
implications and making it harder for the compiler to optimize.

Personally, I think SSE2 did the right thing with its DAZ flag (and 
SSE got half of with with DNZ). The IEEE standard was defined for 
machines with quite different performance and hardware characteristics 
than todays uses. (Even back then, denormals were feared, because they 
introduce unknowable precision loss into your calculation.)

Cheers,

			/ h+


-----Original Message-----
From: ode-bounces at q12.org [mailto:ode-bounces at q12.org]On Behalf Of GARY
VANSICKLE
Sent: Monday, April 26, 2004 5:17 PM
To: ode at q12.org
Subject: RE: [ODE] What is the ODE approach to denormals?


[snip]
> -    if (v[i] > 0) {
> +    //  Denormals are a problem, because we divide by v[i], and then
> +    //  multiply that by 0. Alas, infinity times 0 is infinity (!)
> +    //  We also use v2[i], which is v[i] squared. Here's how the epsilons
> +    //  are chosen:
> +    //  float epsilon = 1.175494e-038 (smallest non-denormal number)
> +    //  double epsilon = 2.225074e-308 (smallest non-denormal number)
> +    //  For single precision, choose an epsilon such that v[i] squared is
> +    //  not a denormal; this is for performance.
> +    //  For double precision, choose an epsilon such that v[i] is not a
> +    //  denormal; this is for correctness.
> +#if defined( dSINGLE )
> +    if (v[i] > dReal(1e-19))
> +#else
> +    if (v[i] > dReal(1e-307))
> +#endif
> +    {
> 
> 
> 
> Is this the right approach?

In concept, probably yes.  In particulars, probably no.  I'd have to
educatedly guess that the smallest non-denormal numbers are going to vary
depending on the underlying hardware, not simply whether we're using float
or double.  This looks like a job for <limits>.  In particular, check this
bit of one popular <limits> out:

enum float_denorm_style {
   denorm_indeterminate = -1,
   denorm_absent = 0,
   denorm_present = 1
   };

Ouch: we might not even know if we have denormals!

_______________________________________________
ODE mailing list
ODE at q12.org
http://q12.org/mailman/listinfo/ode




More information about the ODE mailing list