0

I haven't ever had to deal with this before. I need to convert a sale amount (48.58) to a 4 byte array and use network byte order. The code below is how I am doing it, but it is wrong and I am not understanding why. Can anyone help?

float saleamount = 48.58F; 
byte[] data2 = BitConverter.GetBytes(saleamount).Reverse().ToArray();

What I am getting is 66 66 81 236 in the array. I am not certain what it should be though. I am interfacing with a credit card terminal and need to send the amount in "4 bytes, fixed length, max value is 0xffffffff, use network byte order"

Gergo Erdosi
  • 40,904
  • 21
  • 118
  • 94
Kevin
  • 101
  • 8
  • 1
    "I am not certain what it should be though."... so how do you know it is wrong? looks pretty legit to me ;-) or: does it expect an integer representing the number (treating the float as a fixed fixed point value)? – olydis Jun 04 '14 at 22:22
  • 1
    Also, can I recommend instead of blindly using Reverse(), to check BitConverter.IsLittleEndian first? – itsme86 Jun 04 '14 at 22:24
  • 4
    Are you certain that the terminal is expecting an IEEE single? If I were designing a credit card terminal, I would not use that data type. – phoog Jun 04 '14 at 22:24
  • 1
    Also consider [IPAddress.HostToNetworkOrder](http://msdn.microsoft.com/en-us/library/653kcke1(v=vs.110).aspx). That is, assuming this interface was written correctly to not use floating-point monetary values. – Peter Huene Jun 04 '14 at 22:26
  • What's the maximum monetary value the protocol accepts? For example, this assertion succeeds: `Assert.AreEqual(1000000.0f, 1000000.01f);`. If you are processing values of that magnitude, you *can't* be using IEEE single to represent the values. – phoog Jun 04 '14 at 22:35
  • In testing the 66 66 81 236 ended up being over 8 million dollars. I believe I have to remove the decimal point. – Kevin Jun 05 '14 at 13:14

2 Answers2

0

Network byte order pseudo-synonym of big-endian, hence (as itsme86 mentioned already) so you can check BitConverter.IsLittleEndian:

        float saleamount = 48.58F;
        byte[] data2 = BitConverter.IsLittleEndian
            ? BitConverter.GetBytes(saleamount).Reverse().ToArray()
            : BitConverter.GetBytes(saleamount);

But if you don't know this, probably you already using some protocol, which handle it.

becike
  • 195
  • 1
  • 8
0

The first question you should ask is, "What data type?" IEEE single-precision float? Twos-complement integer? It's an integer, what is the implied scale? Is $48.53 represented as 4,853 or 485,300?

It's not uncommon for monetary values to be represented by an integer with an implied scale of either +2 or +4. In your example, $48.58 would be represented as the integer value 4858 or 0x000012FA.

Once you've established what they actually want...use an endian-aware BitConverter or BinaryWriter to create it. Jon Skeet's MiscUtil, for instance offers:

  • EndianBinaryReader
  • EndianBinaryWriter
  • BigEndianBitConverter
  • LittleEndianBitConverter

There are other implementations out there as well. See my answer to the question "Helpful byte array extensions to handle BigEndian data" for links to some.

Code you don't write it code you don't have to maintain.

Community
  • 1
  • 1
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • I believe you are correct, I am in the process of testing without using a decimal point in the value. I will update once I get results. – Kevin Jun 05 '14 at 13:16
  • That was it sir! I need to remove the decimal point. Thank You. – Kevin Jun 05 '14 at 14:39