http://www.perlmonks.org?node_id=984141

Of the 2**64 possible bit patterns a double can take on only 99.90234375% of them are used to store normal (normalised) floating point values (including +0 & -0).

Of the rest, some 18,014,398,509,481,984 bit patterns:

#! perl -slw use strict; no warnings 'portable'; use constant { POS_ZERO => 0b0_00000000000_0000_00000000_00000000_00000000_000 +00000_00000000_00000000, POS_DENORM_1ST => 0b0_00000000000_0000_00000000_00000000_00000000_000 +00000_00000000_00000001, POS_DENORM_LST => 0b0_00000000000_1111_11111111_11111111_11111111_111 +11111_11111111_11111111, POS_NORM_1ST => 0b0_00000000001_0000_00000000_00000000_00000000_000 +00000_00000000_00000000, POS_NORM_LST => 0b0_11111111110_1111_11111111_11111111_11111111_111 +11111_11111111_11111111, POS_INF => 0b0_11111111111_0000_00000000_00000000_00000000_000 +00000_00000000_00000000, POS_SNAN_1ST => 0b0_11111111111_0000_00000000_00000000_00000000_000 +00000_00000000_00000001, POS_SNAN_LST => 0b0_11111111111_0111_11111111_11111111_11111111_111 +11111_11111111_11111111, POS_QNAN_1ST => 0b0_11111111111_1000_00000000_00000000_00000000_000 +00000_00000000_00000000, POS_QNAN_LST => 0b0_11111111111_1111_11111111_11111111_11111111_111 +11111_11111111_11111111, NEG_ZERO => 0b1_00000000000_0000_00000000_00000000_00000000_000 +00000_00000000_00000000, NEG_DENORM_1ST => 0b1_00000000000_0000_00000000_00000000_00000000_000 +00000_00000000_00000001, NEG_DENORM_LST => 0b1_00000000000_1111_11111111_11111111_11111111_111 +11111_11111111_11111111, NEG_NORM_1ST => 0b1_00000000001_0000_00000000_00000000_00000000_000 +00000_00000000_00000000, NEG_NORM_LST => 0b1_11111111110_1111_11111111_11111111_11111111_111 +11111_11111111_11111111, NEG_INF => 0b1_11111111111_0000_00000000_00000000_00000000_000 +00000_00000000_00000000, NEG_SNAN_1ST => 0b1_11111111111_0000_00000000_00000000_00000000_000 +00000_00000000_00000001, NEG_SNAN_LST => 0b1_11111111111_0111_11111111_11111111_11111111_111 +11111_11111111_11111111, NEG_IND => 0b1_11111111111_1000_00000000_00000000_00000000_000 +00000_00000000_00000000, NEG_QNAN_1ST => 0b1_11111111111_1000_00000000_00000000_00000000_000 +00000_00000000_00000001, NEG_QNAN_LST => 0b1_11111111111_1111_11111111_11111111_11111111_111 +11111_11111111_11111111, }; printf "%23.16g : %016x\n", unpack( 'd', pack 'Q', $_ ), $_ for POS_ZERO, POS_DENORM_1ST, POS_DENORM_LST, POS_NORM_1ST, POS_NORM_L +ST, POS_INF, POS_SNAN_1ST, POS_SNAN_LST, POS_QNAN_1ST, POS_QNAN_LST, NEG_ZERO, NEG_DENORM_1ST, NEG_DENORM_LST, NEG_NORM_1ST, NEG_NORM_L +ST, NEG_INF, NEG_SNAN_1ST, NEG_SNAN_LST, NEG_IND, NEG_QNAN_1ST, NEG_QNAN_LST;

Produces:

C:\test>ieee.pl 0 : 0000000000000000 4.940656458412465e-324 : 0000000000000001 2.225073858507201e-308 : 000fffffffffffff 2.225073858507201e-308 : 0010000000000000 1.797693134862316e+308 : 7fefffffffffffff 1.#INF : 7ff0000000000000 1.#SNAN : 7ff0000000000001 1.#SNAN : 7ff7ffffffffffff 1.#QNAN : 7ff8000000000000 1.#QNAN : 7fffffffffffffff -0 : 8000000000000000 -4.940656458412465e-324 : 8000000000000001 -2.225073858507201e-308 : 800fffffffffffff -2.225073858507201e-308 : 8010000000000000 -1.797693134862316e+308 : ffefffffffffffff -1.#INF : fff0000000000000 -1.#SNAN : fff0000000000001 -1.#SNAN : fff7ffffffffffff -1.#IND : fff8000000000000 -1.#QNAN : fff8000000000001 -1.#QNAN : ffffffffffffffff

For completeness, here is the equivelent code in C:

#include <stdio.h> #include <float.h> typedef unsigned __int64 U64; U64 dblPatns[] = { 0x0000000000000000, // +zero 0x0000000000000001, // +denorm lo 0x000fffffffffffff, // +denorm hi 0x0010000000000000, // +norm lo 0x7fefffffffffffff, // +norm hi 0x7ff0000000000000, // +infinity 0x7ff0000000000001, // +sNAN lo 0x7ff7ffffffffffff, // +sNAN hi 0x7ff8000000000000, // +qNAN lo 0x7fffffffffffffff, // +qNAN hi 0x8000000000000000, // -zero 0x8000000000000001, // -denorm lo 0x800fffffffffffff, // -denorm hi 0x8010000000000000, // -norm lo 0xffefffffffffffff, // -norm hi 0xfff0000000000000, // -infinity 0xfff0000000000001, // -sNAN lo 0xfff7ffffffffffff, // -sNAN hi 0xfff8000000000000, // -IND ?? 0xfff8000000000001, // -qNAN lo 0xffffffffffffffff // -qNAN hi }; double asDouble( U64 u ) { return *(double*)&u; } char *FPClassAsText( int class ) { switch( class ) { case _FPCLASS_SNAN: return "Signaling NaN"; break; case _FPCLASS_QNAN: return "Quiet NaN"; break; case _FPCLASS_NINF: return "Negative infinity (–INF)"; break; case _FPCLASS_NN : return "Negative normalized non-zero"; bre +ak; case _FPCLASS_ND : return "Negative denormalized"; break; case _FPCLASS_NZ : return "Negative zero (-0)"; break; case _FPCLASS_PZ : return "Positive zero (+0)"; break; case _FPCLASS_PD : return "Positive denormalized"; break; case _FPCLASS_PN : return "Positive normalized non-zero"; bre +ak; case _FPCLASS_PINF: return "Positive infinity (+INF)"; break; default: return "Never happen; but silence the warn +ing"; } } int main( int argc, char **argv ) { int i; for( i = 0; i < sizeof( dblPatns ) / sizeof( U64 ); ++i ) printf( "%016I64x : % 23.16g %s\n", dblPatns[ i ], asDouble( dblPatns[ i ] ), FPClassAsText( _fpclass( asDouble( dblPatns[ i ] ) ) ) ); }

Which produces:

C:\test>qnan 0000000000000000 : 0 Positive zero (+0) 0000000000000001 : 4.940656458412465e-324 Positive denormalized 000fffffffffffff : 2.225073858507201e-308 Positive denormalized 0010000000000000 : 2.225073858507201e-308 Positive normalized non-zer +o 7fefffffffffffff : 1.797693134862316e+308 Positive normalized non-zer +o 7ff0000000000000 : 1.#INF Positive infinity (+INF) 7ff0000000000001 : 1.#SNAN Signaling NaN 7ff7ffffffffffff : 1.#SNAN Signaling NaN 7ff8000000000000 : 1.#QNAN Quiet NaN 7fffffffffffffff : 1.#QNAN Quiet NaN 8000000000000000 : -0 Negative zero (-0) 8000000000000001 : -4.940656458412465e-324 Negative denormalized 800fffffffffffff : -2.225073858507201e-308 Negative denormalized 8010000000000000 : -2.225073858507201e-308 Negative normalized non-zer +o ffefffffffffffff : -1.797693134862316e+308 Negative normalized non-zer +o fff0000000000000 : -1.#INF Negative infinity (-INF) fff0000000000001 : -1.#SNAN Signaling NaN fff7ffffffffffff : -1.#SNAN Signaling NaN fff8000000000000 : -1.#IND Quiet NaN fff8000000000001 : -1.#QNAN Quiet NaN ffffffffffffffff : -1.#QNAN Quiet NaN

Note how the oddball -1.#IND is labeled as "Quiet NaN" by the runtime library _fpclass() routine.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

The start of some sanity?