Just another Perl shrine PerlMonks

### Comment on

 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;

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?

Title:
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.
• 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: & & < < > > [ [ ] ]
• Link using PerlMonks shortcuts! What shortcuts can I use for linking?

Create A New User
Chatterbox?
and cookies bake in the oven...

How do I use this? | Other CB clients
Other Users?
As of 2018-01-18 03:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How did you see in the new year?

Results (206 votes). Check out past polls.

Notices?