Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Converting a long to bytes for efficient transmission

I’m creating a serialisation format, and part of the header is the length of the body.

To do this, I’m allocating a fixed number of bytes (currently 4) which I want to use to store as long a number as possible.

As a result I want to store a long in a byte[] (I guess this could be called base 256?).

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here is my code:

long val = 25484394;
var encoded = new byte[4];

var max = 0L;

for (var i = 0; i < encoded.Length; ++i)
{
    max += (long)Math.Pow((int)byte.MaxValue, i);
}

if (val >= max)
    throw new ArgumentOutOfRangeException("value", $"{val} is too large to be encoded (max value is {max})");
    
    for (var i = encoded.Length - 1; i > 0; i--)
    {
//This line is wrong
        encoded[i] = (byte)(int)Math.Floor(val / Math.Pow(byte.MaxValue, i));
    }

What am I doing wrong?

>Solution :

To convert a long value to a byte array (i.e., base 256), you’ll need to use bitwise operations. Let’s break it down step by step.

Ensure you’re not going over the limit:
A 4-byte (32-bit) space can represent values from 0 to 2^32 - 1. So, max should be 2^32 - 1 (which is 4294967295), not the sum you calculated using byte.MaxValue.

Converting the long to bytes:
To obtain the bytes that make up a long, you can perform bit masking and shifting. For each byte you want to extract:

  • Use bitwise AND (&) with a mask of 0xFF to obtain the least significant 8 bits of the value.
  • Store the result in your byte array.
  • Right-shift the original value by 8 bits to move on to the next byte.

Here’s a corrected version of your code:

long val = 25484394;
var encoded = new byte[4];

// A 4-byte (32-bit) space can represent values from 0 to 2^32 - 1.
long max = (1L << 32) - 1;

if (val > max)
    throw new ArgumentOutOfRangeException("value", $"{val} is too large to be encoded (max value is {max})");

for (var i = 0; i < encoded.Length; i++)
{
    encoded[encoded.Length - 1 - i] = (byte)(val & 0xFF);
    val >>= 8; // Right shift the value by 8 bits
}

Here’s what’s happening:

  • The mask 0xFF will get the least significant 8 bits of val.
  • After we’ve taken these bits and stored them, we shift val right by 8 bits so the next 8 bits will be in the least significant position for the next iteration. This process continues until we’ve filled the entire encoded array.

Note: It’s important to handle situations where val is negative or beyond the range of the byte array. The code above assumes val is always non-negative and you’re doing a check for the maximum allowable value. If there’s a chance val can be negative, you’ll need to add another check for that.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading