Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

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:

  • two are used to represent +infinity and -infinity.

    Numbers too big or too small to be represented respectively.

  • 9,007,199,254,740,988 are used to represent denormalised real values.

    In decimal, 3.14159e0 is normalised. Whereas 0.314159e1 & 31.4159e-1 represent the same number, but are denormalised.

  • 18,442,240,474,082,181,118 are used to represent signalling NANs. Half positive; half negative.

    When produced by a mathematical operation, signalling NaNs cause an immediate trap. They represent invalid operations.

  • 18,442,240,474,082,181,117 are used to represent quiet NANs. Half positive; half-1 negative.

    When produced, quiet NaNs don't immediately trap, but rather propogate through subsequent operations they are involved in. They represent indeterminate results.

  • And the remaining 1 is assigned (by the MSC compiler at least) to "indeterminate" -1.#IND.

    There doesn't appear to be a positive 1.#IND (on MSC).

    Numerically, this sits in the negative qNaN range -- which are all "indeterminate".

    Quite why this one value -- from the 18 quintillion -- is singled out for special treatment I have yet to discover.

#! 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;


C:\test> 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?

In reply to Exploring IEEE754 floating point bit patterns. by BrowserUk

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others avoiding work at the Monastery: (6)
    As of 2018-06-19 03:44 GMT
    Find Nodes?
      Voting Booth?
      Should cpanminus be part of the standard Perl release?

      Results (111 votes). Check out past polls.