Harkening back to my experiments to make an Expand.pm to interpret IEEE754 doubles, I found when making my tests that as I converted a signaling NaN bit string into a double then back to the bit string, it became a quiet NaN. At first I thought I just had a bug in my conversion, so then I tried BrowserUK's code from Re^2: Exploring IEEE754 floating point bit patterns., along with a new function to convert it back.

#!/usr/bin/perl use warnings; use strict; use lib '.'; use Tools; # local == Data::IEEE754::Tools use constant { POS_ZERO => '0'.'00000000000'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000000', POS_DENORM_1ST => '0'.'00000000000'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000001', POS_DENORM_LST => '0'.'00000000000'.'1111'.'11111111'.'11111111'. +'11111111'.'11111111'.'11111111'.'11111111', POS_NORM_1ST => '0'.'00000000001'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000000', POS_NORM_LST => '0'.'11111111110'.'1111'.'11111111'.'11111111'. +'11111111'.'11111111'.'11111111'.'11111111', POS_INF => '0'.'11111111111'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000000', POS_SNAN_1ST => '0'.'11111111111'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000001', POS_SNAN_LST => '0'.'11111111111'.'0111'.'11111111'.'11111111'. +'11111111'.'11111111'.'11111111'.'11111111', POS_IND => '0'.'11111111111'.'1000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000000', POS_QNAN_1ST => '0'.'11111111111'.'1000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000001', POS_QNAN_LST => '0'.'11111111111'.'1111'.'11111111'.'11111111'. +'11111111'.'11111111'.'11111111'.'11111111', NEG_ZERO => '1'.'00000000000'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000000', NEG_DENORM_1ST => '1'.'00000000000'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000001', NEG_DENORM_LST => '1'.'00000000000'.'1111'.'11111111'.'11111111'. +'11111111'.'11111111'.'11111111'.'11111111', NEG_NORM_1ST => '1'.'00000000001'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000000', NEG_NORM_LST => '1'.'11111111110'.'1111'.'11111111'.'11111111'. +'11111111'.'11111111'.'11111111'.'11111111', NEG_INF => '1'.'11111111111'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000000', NEG_SNAN_1ST => '1'.'11111111111'.'0000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000001', NEG_SNAN_LST => '1'.'11111111111'.'0111'.'11111111'.'11111111'. +'11111111'.'11111111'.'11111111'.'11111111', NEG_IND => '1'.'11111111111'.'1000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000000', NEG_QNAN_1ST => '1'.'11111111111'.'1000'.'00000000'.'00000000'. +'00000000'.'00000000'.'00000000'.'00000001', NEG_QNAN_LST => '1'.'11111111111'.'1111'.'11111111'.'11111111'. +'11111111'.'11111111'.'11111111'.'11111111', }; my @list = ( POS_ZERO, POS_DENORM_1ST, POS_DENORM_LST, POS_NORM_1ST, POS_NORM_L +ST, POS_INF, POS_SNAN_1ST, POS_SNAN_LST, POS_IND, 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 ); sub bitsToDouble{ unpack 'd', pack 'b64', scalar reverse $_[0] } sub bitsToInts{ reverse unpack 'VV', pack 'b64', scalar reverse $_[0 +] } sub doubleToBits{ scalar reverse unpack 'b64', pack 'd', $_[0] } printf "%23.16g : %08x%08x >=there-and-back-again=> %08x%08x\n", bitsToDouble( $_ ), bitsToInts( $_ ), bitsToInts( doubleToBits( bitsToDouble( $_ ) ) ) for @list; print "\n"; use Test::More tests => 22; is( doubleToBits( bitsToDouble( $_ ) ) , $_ , "bitsToDouble(doubleToBi +ts($_))" ) for @list;

outputs

0 : 0000000000000000 >=there-and-back-again=> 00 +00000000000000 4.940656458412465e-324 : 0000000000000001 >=there-and-back-again=> 00 +00000000000001 2.225073858507201e-308 : 000fffffffffffff >=there-and-back-again=> 00 +0fffffffffffff 2.225073858507201e-308 : 0010000000000000 >=there-and-back-again=> 00 +10000000000000 1.797693134862316e+308 : 7fefffffffffffff >=there-and-back-again=> 7f +efffffffffffff Inf : 7ff0000000000000 >=there-and-back-again=> 7f +f0000000000000 NaN : 7ff0000000000001 >=there-and-back-again=> 7f +f8000000000001 NaN : 7ff7ffffffffffff >=there-and-back-again=> 7f +ffffffffffffff NaN : 7ff8000000000000 >=there-and-back-again=> 7f +f8000000000000 NaN : 7ff8000000000001 >=there-and-back-again=> 7f +f8000000000001 NaN : 7fffffffffffffff >=there-and-back-again=> 7f +ffffffffffffff -0 : 8000000000000000 >=there-and-back-again=> 80 +00000000000000 -4.940656458412465e-324 : 8000000000000001 >=there-and-back-again=> 80 +00000000000001 -2.225073858507201e-308 : 800fffffffffffff >=there-and-back-again=> 80 +0fffffffffffff -2.225073858507201e-308 : 8010000000000000 >=there-and-back-again=> 80 +10000000000000 -1.797693134862316e+308 : ffefffffffffffff >=there-and-back-again=> ff +efffffffffffff -Inf : fff0000000000000 >=there-and-back-again=> ff +f0000000000000 NaN : fff0000000000001 >=there-and-back-again=> ff +f8000000000001 NaN : fff7ffffffffffff >=there-and-back-again=> ff +ffffffffffffff NaN : fff8000000000000 >=there-and-back-again=> ff +f8000000000000 NaN : fff8000000000001 >=there-and-back-again=> ff +f8000000000001 NaN : ffffffffffffffff >=there-and-back-again=> ff +ffffffffffffff ... not ok 7 - bitsToDouble(doubleToBits(011111111111000000000000000000000 +0000000000000000000000000000001)) # Failed test 'bitsToDouble(doubleToBits(011111111111000000000000000 +0000000000000000000000000000000000001))' # at ...\buk.pl line 52. # got: '01111111111110000000000000000000000000000000000000000 +00000000001' # expected: '01111111111100000000000000000000000000000000000000000 +00000000001' not ok 8 - bitsToDouble(doubleToBits(011111111111011111111111111111111 +1111111111111111111111111111111)) # Failed test 'bitsToDouble(doubleToBits(011111111111011111111111111 +1111111111111111111111111111111111111))' # at ...\buk.pl line 52. # got: '01111111111111111111111111111111111111111111111111111 +11111111111' # expected: '01111111111101111111111111111111111111111111111111111 +11111111111' ... not ok 18 - bitsToDouble(doubleToBits(11111111111100000000000000000000 +00000000000000000000000000000001)) # Failed test 'bitsToDouble(doubleToBits(111111111111000000000000000 +0000000000000000000000000000000000001))' # at ...\buk.pl line 52. # got: '11111111111110000000000000000000000000000000000000000 +00000000001' # expected: '11111111111100000000000000000000000000000000000000000 +00000000001' not ok 19 - bitsToDouble(doubleToBits(11111111111101111111111111111111 +11111111111111111111111111111111)) # Failed test 'bitsToDouble(doubleToBits(111111111111011111111111111 +1111111111111111111111111111111111111))' # at ...\buk.pl line 52. # got: '11111111111111111111111111111111111111111111111111111 +11111111111' # expected: '11111111111101111111111111111111111111111111111111111 +11111111111' ...

... ie, it fails on just the signaling NaN, appearing like a quiet NaN bitstring.

I tried under an ancient CentOS 4.6 perl 5.8.5, and under a recent Strawberry 5.22.1 32bit, and get the same quieting of the sNaN. Am I doing something wrong, or does perl just automatically quiet signalling NaN values?


In reply to unintentional conversion of signaling NaN to quiet NaN by pryrt

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.
  • 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, details, 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, summary, 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.