Freedom-of-Form-Foundation / anatomy3d

A CAD tool for humanoid anatomy alterations. See the anatomy3d-blender repository for more recent work.
https://freedomofform.org/1856/3d-anatomy-project-scope-phase-1-focus-on-a-limb-joint/
GNU General Public License v2.0
7 stars 5 forks source link

Add IsNormal() and IsSubnormal() functions in the Real struct #42

Closed Lathreas closed 3 years ago

Lathreas commented 3 years ago

Since we will be checking for 'numbers so small they have precision loss', we need a proper function to check for these regardless of the underlying type. An interesting way to check is whether the number is 'normal' or 'subnormal'. A floating point value can be subnormal if the exponent of the floating point underflows and instead leading zeros are added in the decimal part. As a result, the decimal part is no longer 'normalized', and the value is called 'subnormal'.

The C99 and C++11 standards define an isnormal(x) macro/function that returns whether x is a normal value. It returns true if x is not infinity, NaN, zero, or subnormal. Likewise, it returns false when x is either infinity, NaN, zero, or subnormal.

It will be very useful to have this function defined for the Real struct as well.

IsNormal() would return true when a number is not infinity, NaN, zero, or subnormal.

IsSubnormal() would check whether a number is subnormal. According to wikipedia,

Any non-zero number with magnitude smaller than the smallest normal number is subnormal.

This means that IsSubnormal() should return true when the value is subnormal, but false when the value is exactly zero, normal, infinite or NaN. I have been unable to find a fitting behavior for negative 0.0 in any documentation so far (sadly the .NET docs are quite vague regarding the exact behavior of the .NET 5.0 variants).

There exists a nice bitwise check to see if a number is normal or subnormal, according to this stackoverflow issue: https://stackoverflow.com/questions/26575345/how-to-check-in-c-sharp-if-the-given-double-number-is-normal-i-e-is-neither-ze

There should be one for single-precision floats as well.