Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^10: NaN output

by BrowserUk (Patriarch)
on Mar 06, 2014 at 13:53 UTC ( [id://1077232]=note: print w/replies, xml ) Need Help??


in reply to Re^9: NaN output
in thread NaN output

you could start with a couple of IV's and generate a NaN.

The problem (for me) is that there are no IVs involved in your construction.

The basic compile-time constant: 2**1025 never results in the construction of any IVs.

The interpreter constructs a compile-time constant from the expression and stores it as an NV:

Perl> use Devel::Peek;; Perl> $x = 2**1025;; Perl> Dump( $x );; SV = NV(0xb4598) at 0x3d73ee8 REFCNT = 1 FLAGS = (NOK,pNOK) NV = 1.#INF

And then at runtime, one NV (value 1.#INF) is divided by another NV (also 1.#INF) and the results is an NV (value: -1.#IND):

$y = $x / $x;; Dump $y;; SV = NV(0xb45a0) at 0x3d6c6a8 REFCNT = 1 FLAGS = (NOK,pNOK) NV = -1.#IND

No IVs were ever involved because the textual integer expression from the source code never made into the byte-coded Perl.


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.

Replies are listed 'Best First'.
Re^11: NaN output
by syphilis (Archbishop) on Mar 06, 2014 at 23:46 UTC
    The problem (for me) is that there are no IVs involved in your construction

    C:\>perl -MDevel::Peek -le "Dump(2);" SV = IV(0x1daf1b8) at 0x1daf1bc REFCNT = 1 FLAGS = (PADTMP,IOK,READONLY,pIOK) IV = 2 C:\>perl -MDevel::Peek -le "Dump(1025);" SV = IV(0x53ee70) at 0x53ee74 REFCNT = 1 FLAGS = (PADTMP,IOK,READONLY,pIOK) IV = 1025
    Or, alternatively, I could have assigned the values 2 and 1025 to two IV's.

    The interpreter constructs a compile-time constant from the expression and stores it as an NV.


    Yes, nothing remarkable about that - most perl users (you and I included) are aware of this and generally comfortable with it.
    However, it implies to me that in perl, there are no distinct realms of ints and floats. And your remark that "NaN is a purely floating point concept" (which is correct) suddenly seemed a bit blurry wrt perl - because, in so many ways, perl doesn't draw a line between floats and ints - yet it does have NaNs.

    Anyway ... I should have tried harder to explain the triviality or, better still, just made a mental note of it and said nothing.

    I sure am glad I didn't create a demo where the upgrade from IV to NV occurred because of integer overflow ... then manipulate the NV to create a NaN ... then claim to have shown that a NaN *can* arise from integer overflow. Something like:
    C:\>perl -le "$x= ~0; $x += 2; $x **= 35; $x /= $x; print $x;" -1.#IND
    ;-))

    (Complete and utter sophistry, of course.)

    Cheers,
    Rob

      Hm. $x starts undefined

      [0] Perl> use Devel::Peek;; [0] Perl> Dump $x;; SV = NULL(0x0) at 0x3c6d400 REFCNT = 1 FLAGS = ()

      You set $x to the maximum unsigned integer value; it becomes an IV:

      [0] Perl> $x = ~0;; [0] Perl> Dump $x;; SV = IV(0x3c6d3f8) at 0x3c6d400 REFCNT = 1 FLAGS = (IOK,pIOK,IsUV) UV = 18446744073709551615

      You add 2 to it, it overflows the IV, so perl converts it to an NV (NB: No NaN arises from the overflow of the IV.)

      [0] Perl> $x += 2;; [0] Perl> Dump $x;; SV = PVNV(0x3cb85e8) at 0x3c6d400 REFCNT = 1 FLAGS = (NOK,pNOK) IV = -1 NV = 1.84467440737096e+019 PV = 0

      Then, you raise that NV to the power 35; and the NV overflows; resulting in an NV with the floating point value of positive infinity (1.#INF) (NB:the "result to large" error):

      [0] Perl> $x **=35;; [Result too large] Perl> Dump $x;; SV = PVNV(0x3cb85e8) at 0x3c6d400 REFCNT = 1 FLAGS = (NOK,pNOK) IV = -1 NV = 1.#INF PV = 0

      You then divide the NV 1.#INF, by itself, and you produce an indeterminate floating point value (1.#IND):

      [0] Perl> $x /= $x;; [0] Perl> Dump $x;; SV = PVNV(0x3cb85e8) at 0x3c6d400 REFCNT = 1 FLAGS = (NOK,pNOK) IV = -1 NV = -1.#IND PV = 0

      The (special form of) NaN was produced by operating upon (erroneous) floating point (NV) values; not integer (IV) overflow.

      NaN is a purely floating point concept, and cannot arise as a result of integer overflow.


      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.
        Nothing there that I didn't already know, though the phrase "(erroneous) floating point (NV) values" did catch my eye. I'm wondering why "(erroneous)" is in there.

        I've not previously encountered the notion that an infinity is an *erroneous* floating point value. (Or, if I have encountered it, I've not paid due attention to it.)
        Did I misconstrue ?

        Cheers,
        Rob

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1077232]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-03-28 09:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found