Thursday, February 17, 2011

Is the binary data I convert to a Short valid?

Howdy,

I am reading a binary log file produced by a piece of equipment.

I have the data in a byte[].

If I need to read two bytes to create a short I can do something like this:

short value = (short)(byte[1] << 8);
value += byte[2];

Now I know the value is the correct for valid data.

How would I know if the file was messed up and lets say the values FF FF were in those two places in the byte array?

When I look at the resultant value of converting FF FF to a short, I get a -1.

Is this a normal value for FF FF?, or did the computer just hit some kind of short bound and roll over with invalid data?

For my purposes all of theses numbers are going to be positive. If FF FF is actually a short -1, then I just need to validate that all my results are postitive.

Thank you,
Keith

BTW, I am also reading other number data types. I'll show them here just because. The Read function is the basic part of reading from the byte[]. All the other data type reads use the basic Read() function.

    public byte Read()
    {
        //advance position and then return byte at position 

        byte returnValue;
        if (_CurrentPosition < _count - 1)
        {
            returnValue= _array[_offset + ++_CurrentPosition];
            return returnValue;
        }
        else
            throw new System.IO.EndOfStreamException
                   ("Cannot Read Array, at end of stream."); 
    }


    public float ReadFloat()
    {
        byte[] floatTemp = new byte[4];
        for (int i = 3; i >= 0; i--)
        {
            floatTemp[i] = Read();
        }

        float returnValue = System.BitConverter.ToSingle
            (floatTemp, 0);

        if (float.IsNaN(returnValue))
        {
            throw new Execption("Not a Number");    
        }
        return returnValue;
    }


    public short ReadInt16()
    {
        short returnValue = (short)(Read() << 8);
        returnValue += Read();
        return returnValue;
    }

    public int ReadInt32()
    {
        int returnValue = Read() << 24;
        returnValue += Read() << 16;
        returnValue += Read() << 8;
        returnValue += Read();
        return returnValue;
    }
From stackoverflow
  • Did you try to use ushort (unsigned short)?

  • The value of FFFF for a "short" is -1 but the value of FFFF for an "unsigned short" is 65536.

    In this case you should make sure you are using an unsigned short if you are sure that all of your values will be positive.

  • 0xffff (all bits equal to 1) is -1 for signed shorts, yes. Read up on Two's complement to learn more about the details. You can switch to a larger datatype, or (as suggested by Grzenio) just use an unsigned type.

    Keith Sirmons : Neat stuff on the Two's complement. http://en.wikipedia.org/wiki/Twos_complement
  • Well, you seemed to have found BitConverter for singles. Now let's see if we can get to to use it for everything else as well...

    MemoryStream mem = new MemoryStream(_array);
    
    
    float ReadFloat(Stream str)
    {
       byte[] bytes = str.Read(out bytes, 0, 4);
       return BitConverter.ToSingle(bytes, 0)
    }
    
    public int ReadInt32(Stream str)
    {
       byte[] bytes = str.Read(out bytes, 0, 4);
       return BitConverter.ToInt32(bytes, 0)
    }
    
    Keith Sirmons : Would there be a performance gain or loss switching to this method? I would also have to write the Read(out byte[], offset, length) method. Thank you for the suggestions.
  • I think you would be better served using the System.BitConverter class.

    Specifically for shorts the ToInt16 method.

    You didn't mention it in your question, but you should also make sure that you know what endianess the hardware device is writing its data in. From your examples it looks like the float is in little endian, but the integers are in big endian? I doubt a hardware device would mix endianess in its output of binary data.

    Keith Sirmons : The machine is mixing it's little and big endians.
    grieve : Odd! In that case you can still use ToInt16 and its methods, then swap the bytes. This puts all your byte swapping in one function (or family of functions). This is discussed in more detail here: http://blogs.msdn.com/jeremykuhne/archive/2005/07/21/441247.aspx
  • Yes 0xFFFF is -1 for a signed short.

    Also, why wouldn't you use the BinaryReader class?

0 comments:

Post a Comment