Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# 3 byte Ints

Tags:

int

byte

I am working on a project where I need to deal at the byte level with integers. Since saving space is a primary consideration, I only need very small (and variable length ints).

Is there a way that I can turn the int '4096' into 3 bytes? or '1053' into a 2 bytes?

Obviously I cna do it manually = (byte[0] * 256) + (byte[1]), but i was wondering if there is an easier option to convert the int into x bytes and back again?

like image 357
Ash Avatar asked Nov 28 '22 16:11

Ash


2 Answers

Can you? Sure. Will it save any space? Maybe, depending on how much work you want to do. You have to understand that the processor is 32-bit, meaning it has 4 byte registers, so that's how it's going to want to store and access things. To force a 3-byte "int" you'll have to keep it in a byte array, and extract it from the array to an aligned address before use. That means that if you store it short, the compiler will either pad it out (and you'll lose any efficiency you think you've created) or it will be a lot slower to read and write.

If this is a desktop app, how exactly is saving space a primary consideration, especially when talking 1 byte per element? The perf penalty for element access may change you mind about how critical that one byte is.

I'd argue that if that 1 byte truly is important, that maybe, just maybe, you're using the wrong language anyway. The number of bytes you'd save my not installing and using the CLR in the first place is a lot of those bytes.

Side note: You'd also do a shift, not a multiplication (though the compiler would likely get there for you).

like image 140
ctacke Avatar answered Dec 04 '22 20:12

ctacke


Just for added insanity, let's do it in C# using the old C-style union trick:

[StructLayout(LayoutKind.Explicit)]
struct OddUnion
{
    /* The 32-bit integer value */
    [FieldOffset(0)]
    public int IntegerValue;

    /* The bytes that overlap with it */
    [FieldOffset(0)]
    public byte Byte1;
    [FieldOffset(1)]
    public byte Byte2;
    [FieldOffset(2)]
    public byte Byte3;
    [FieldOffset(3)]
    public byte Byte4;
 }

And then, when you want to "convert", do this:

OddUnion myOddUnion;
myOddUnion.IntegerValue = 4096;
Byte secondByte = myOddUnion.Byte1;

But that really only helps if you're looking to "save" the cost of bit-shifting out a single byte from a word. I haven't looked at the generated SMIL, so I don't know whether this is any cheaper in comparison to any other solution.

like image 41
Shalom Craimer Avatar answered Dec 04 '22 21:12

Shalom Craimer