spikeinc has asked for the wisdom of the Perl Monks concerning the following question:

Hi Folks!!!

I have a polling script that polls SNMP counters and keeps adding on the values. The SNMP counter is a 32 bit counter. Now sometimes, when it keeps polling, it gives me an output of NaN as below:

As seen below, after a point, it prints the value as NaN. How can I avoid this?

Tue Mar 4 20:37:58 2014 - Rollover Transferred Till now : 127 +60590224 bytes Tue Mar 4 20:38:09 2014 - MetInStart = 16348693 Tue Mar 4 20:56:12 2014 - Rollover Transferred Till now : NaN + bytes Tue Mar 4 20:56:22 2014 -* ACStart= 5605524 Tue Mar 4 20:59:36 2014 - Rollover AC Transferred Till now : +17039208827 bytes Tue Mar 4 20:59:46 2014 - MetInStart = 12418066 Tue Mar 4 21:17:56 2014 - Rollover Transferred Till now : NaN + bytes Tue Mar 4 21:18:06 2014 -* ACDecryptStart = 8065104 Tue Mar 4 21:21:19 2014 - Rollover AC Transferred Till now : +21321758057 bytes Tue Mar 4 21:21:29 2014 - MetInStart = 29525422 Tue Mar 4 21:39:39 2014 - Rollover - Transferred Till now : N +aN bytes

Replies are listed 'Best First'.
Re: NaN output
by syphilis (Archbishop) on Mar 05, 2014 at 08:01 UTC
    It's hard to work out how this happens from the info you've provided.
    I've not seen a NaN come about as the result of integer overflow as Laurent_R has suggested ... but I don't have an alternative explanation.

    Given that at 20::56::12 "Rollover Transferred Till now" was "NaN bytes", it stands to reason that every subsequent "Rollover - Transferred Till now" will also be "NaN bytes" since NaN + X is always NaN (where X can be any positive, negative, zero, infinite or NaN value).
    So it's probably just a matter of working out how that NaN value gets there in the first place.
    And I can't tell much about that from here. Do you have a small demo script that exhibits the behaviour ?

    Cheers,
    Rob
Re: NaN output
by Laurent_R (Canon) on Mar 05, 2014 at 07:15 UTC
    You presumably get NaN (not a number) when you have an integer overflow on a 32-bit counter (i.e. a number larger than 2^31 - 1 = 2,147,483,647). Either you have a way to use 64 bbits counters or you may be you can use on of the modules for high prevision arithmetics such as BigInt.
      You presumably get NaN (not a number) when you have an integer overflow on a 32-bit counter (i.e. a number larger than 2^31 - 1 = 2,147,483,647). Either you have a way to use 64 bbits counters or you may be you can use on of the modules for high prevision arithmetics such as BigInt.

      NaN is a floating point value and thus has nothing at all to do with numerical limits of integer data types.


      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.
        You are quite right, probably a wrong hypothesis on my part, albeit looking at the values in the data sample supplied in the OP, many come pretty close to the 32-bit signed integer limit, leading to think that the others might just be above it. Actually, thinking again about it, it seems to me that Perl itself (and, I guess pure Perl modules) can handle larger integers (or possibly I am lucky enough to use only 64-bits integers on the platforms I have been using in the recent years). But I have encountered the problem in the past with some modules and I am almost sure that I have also encountered the NaN thing with integers with some of them. It is too long ago for me to remember the details, though, I may confuse different issues. Anyway, we don't know enough about the OP's program to make this type of hypotheses.
Re: NaN output
by BrowserUk (Patriarch) on Mar 05, 2014 at 16:49 UTC

    Are you sure that you are not encountering an endian problem? For example, the 4 byte value 0x7ff00000, decoded as a big-endian float produces a valid number:

    print unpack 'f>', pack 'V', 0x7ff00000;; 8.6273742553086e-041

    But treated as a little-endian value it produces NaN:

    print unpack 'f<', pack 'V', 0x7ff00000;; 1.#QNAN

    Just a thought.


    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.
Re: NaN output
by Anonymous Monk on Mar 05, 2014 at 16:27 UTC
    Chase down where in the loop the first NAN value is coming-from, because it's like the little "E(rror)" indicator in a pocket calculator. As soon as the value is "'not a number' anymore," all arithmetic stops. Write some debugging code that will die as soon as the NAN appears, so that you can find it. Then, a little more debugging stuff to trap where it actually occurs. Arithmetic overflow is a likely culprit but not the only possibility. Minimize guesswork.