Forum Discussion

Eduardo_Saito_1's avatar
Eduardo_Saito_1
Icon for Nimbostratus rankNimbostratus
Sep 25, 2007

STATISTIC_BYTES_OUT with negative numbers.

Hello Everybody.

I'm having the following problem and I hope someone can help me.

I did a .net CSharp program that collects STATISTIC_BYTES_IN and STATISTIC_BYTES_OUT.

It really works when the value is low (lower than 10GB) but when this value is higher I'm getting negative values!

I've notice that the BIG-IP GUI shows interfaces statistics data in Bits not Bytes.

I'm logging these values to help me debug this issue:


(679703814 = 648MB <--- This one works)
9/25/2007 5:52 PM  STATISTIC_BYTES_IN_LOW: 679703814 STATISTIC_BYTES_IN_HIGH: 0
(-1202998967 <--- Why this value is NEGATIVE? It should show aprox 7.3GB)
9/25/2007 5:59 PM  STATISTIC_BYTES_OUT_LOW: -1202998967 STATISTIC_BYTES_OUT_HIGH: 1

Questions:

1) Why the second one shows a NEGATIVE number?

2) Why "STATISTIC_BYTES_OUT_HIGH" shows "1"? What's the difference between LOW and HIGH?

Thanks!

8 Replies

  • Got it.

     

     

    There was a C sample on SDK. Thanks dev team for including this on the SDK!!!!

     

     

    For who want to know the solution:

     

     

    build64(interface_statistics.statistics[ i ].statistics[ j ].value));

     

    UInt64 build64(CommonULong64 value)

     

    {

     

    return ((ulong)value.high<<32)|(uint)value.low;

     

    }

     

     

     

    Thanks!
  • The statistics are returned in a structure with two 32bit signed values

    struct ULong64 {
      long high;
      log low;
    }

    Q: Why have a structure instead of a native 64 bit number?

    A: The XML Schema that we use for typing doesn't support 64 bit numbers and some of the client side tooklits don't support 64 bit numbers natively either.

    Q: Why use signed instead of unsigned values? (or, why is the low value negative in your second example).

    A: We had to use signed values as Java doesn't support unsigned values (at least it didn't when we first developed iControl). By using the unsigned long schema type, we were getting runtime errors with the java toolkits. So we had to use signed numbers. Numbers that go half way over the 32bit mark, will have the highest bit of 1 which indicates a negative number for signed values.

    Q: Why does the high value show a value of 1?

    A: The calculation in C is: 64bit = ((ulong)high<<32) | (uint)low; In your case, the 33rd bit in the 64 bit number is one meaning your number broke the 32bit boundary of 2^32.

    The bottom line is that you should use a helper method to convert your two 32bit signed values into a 64bit unsigned value before you do calculations on it.

    -Joe
  • Hi All,

     

     

    I'm hitting the same problem in Powershell using the following function, given in the code examples on the site:

     

     

        
          function Convert-To64Bit()      
          {      
            param($high, $low)      
            return ($high*[Math]:: Pow(2,32))+$low;      
          }      
        

     

     

    I've purposely put a space between "::" and "Pow" to stop an emoticon being displayed. It's there in my code.

     

     

    Do you have a resolution to get round this issue in Powershell. I see one has been given for Perl http://devcentral.f5.com/Default.aspx?tabid=53&forumid=1&tpage=1&view=topic&postid=3140731407

     

     

    Thanks for your help

     

     

    Gareth
  • Try this out:

      
      [Convert]::ToUint64([Convert]::ToString($high,2).PadLeft(32,'0')+[Convert]::ToString($low,2).PadLeft(32,'0'),2)  
      

    I am not a powershell user and not really sure whether or not it will work perfectly.

  • Thanks all! I'll make sure I use this in all my future tech tips...

     

     

    -Joe
  • Glad you enjoy them! Let me know of any ideas you think would be useful for future tech tips and I'll see what I can do!

     

     

    -Joe
  • For the benefit of anyone working with python, here's how I conquered this problem...

     

     

    The problem with python's number handling is that it's near-impossible to get the straight bitwise representation of an int, especially negative numbers. However, since we know these are 32-bit integers, you can undo the two's compliment encoding and go from there.

     

     

    Unformatted code:

     

    -------

     

    def toLongInt(ulong_64):

     

    """

     

    F5 likes to hand out 64-bit values as a pair of signed 32s.

     

    Need to undo the two's compliment to get the original

     

    integers back, then "bit-concatenate" them.

     

    """

     

    high = ulong_64.high

     

    low = ulong_64.low

     

    Convert both values from signed to unsigned

     

    if high < 0:

     

    high = high + (1<<32)

     

    if low < 0:

     

    low = low + (1<<32)

     

    return long((high<<32)|low)

     

    ---

     

     

    Indent-formatted code at http://pastebin.com/p5EUv3Fh
  • I struggled with the same problem in Python, but I didn't have the ability ot use Jython. In the end used pack and unpack fromthe struct module.

     def hlconvert(high,low):
    if high<0:
    high = unpack('=I', pack('=i',high))[0]
    if low<0:
    low = unpack('=I', pack('=i',low))[0]
    return long((high<<32)|low)