11,435,451 members (55,283 online)

# Binary, octal, and hexadecimal 32 bit structs

, 6 Oct 2008 CPOL
 Rate this:
Simplifies the use of base 2, 8, and 16 bit data.

## Introduction

Although data is obviously stored in memory or on disk in binary form, .NET automatically converts it into base 10 (decimal) whenever we want to see the data or set values. It does have a little functionality for getting or setting values in other bases, as listed below.

## Inbuilt functions

Setting an Int32 (base = 2 for binary, 8 for octal, or 16 for hexadecimal): `Convert.ToInt32 (string, base)`. E.g.:

```string binaryString = "11111111";
int i = Convert.ToInt32 (binaryString, 2);```

`i` now equals 255.

`int i = 0xFF;`
`i` now equals 255.

Getting a value from an Int32: `Convert.ToString (integer, base)`. E.g.:

```int i = 255;
string binaryString = Convert.ToString (i, 2);```

`binaryString` now equals 1111111.

## This class library

These suffice in most situations, but I’ve often found I need a more natural/flexible way that basically wraps these functions up. This class library is a few simple bits of code to address this. All the structs are built around an `Int32` (`m_Value`), so are therefore called `Bin32`, `Oct32`, and `Hex32`.

The first thing you’ll notice in each struct are several `implicit` and one `explicit` operator methods.

In `Bin32`, the first one is:

`public static implicit operator Bin32(int value) {... }`

This bit of magic allows us to accept an `int` directly to create an instance of `Bin32`, without needing to call an overloaded constructor in our code (it's done automatically to a private constructor). You can do this, for example:

`Bin32 binaryValue = 255;`

`Bin32 binaryValue = new Bin32(255);`

The next is similar, but allows us to use a string:

`public static implicit operator Bin32(string value) {... }`

So, we can simply use:

`Bin32 binaryValue = "11111111";`

A little further down is a similar method to the first, but with `Bin32` and `int` reversed.

`public static implicit operator int(Bin32 value) {... }`

This allows us to automatically use our value as an `int` without explicitly casting.

```Bin32 binaryValue = "11111111";
int i = binaryValue;```

The next line is different in that it is `explicit` rather than `implicit`:

`public static explicit operator string(Bin32 value) {... }`

By using the `explicit` keyword, it means we have to explicitly cast to this type to use the method.

```Bin32 binaryValue = "11111111";
string binaryString = (string)binaryValue;```

Why not use `implicit` here? Well, having multiple implicit return types can cause some major headaches. Just try changing the `explicit` to `implicit`, and then try:

`Console.WriteLine(binaryValue);`

Oops! There is a lot of ambiguity created as it doesn’t know what to write to the console – more than one choice is too many!

Initially, I had the `string` as `implicit` and the `int` as `explicit`. It can work fine that way, but a lot more code is needed as all unary, binary, logical, and conditional operators then require overloading. Keeping the `int` as `implicit`, we get to use the code that Microsoft has already done for the `Int32` operators .

As well as the explicit cast there are also the two `ToString` methods (one for `Oct32`).

I’ve implemented the standard `IComparable` and `IEquatable` interfaces. The `Parse`, `ToString`, and `TryParse` methods are mainly covered in by the in-built functions I covered at the beginning of the article.

There is one other class here – a static class called `ExtensionMethods`, where a few simple extension methods are declared to give added functionality to `int`s and `string`s without having to actually call any `Bin32`, `Oct32`, or `Hex32` instances ourselves.

## In use

Add a reference to BinOctHex.dll to your project. Using these structs is very easy. A simple example is attached. All the usual stuff you can do with an `int` can be done with any of these (including bit shifting, which makes more sense in hex and binary). You can also do operations on combinations of these. E.g.:

`(bin number % hexnumber) / octnumber;`

## Motivation for use

I often need to do calculations on multiple binary and hexadecimal numbers and have the results displayed in either base (octal less frequently, but I included it for completeness).

Imagine something simple such as:

`((1 + 2 + 3 + 4 + 5) % 4) * 15 = ?`

Easy if they're all `int`s, but what if they're mixed binary and hex strings?

`((00000001 + 00000010 + 00000011 + 00000100 + 00000101) % 00000100) * 0F = ?(base 8)`

Currently, you'd have to convert each string manually to an `int`, and then convert again to display the answer in the correct base. Using this, you just perform the calculation as it looks.

```string a1 = "00000001";
string b1 = "00000010";
string c1 = "00000011";
string d1 = "00000100";
string e1 = "00000101";
string f1 = "00000100";
string g1 = "0F";

// Using methods built in.
int h1 = (
(Convert.ToInt32(a1, 2) +
Convert.ToInt32(b1, 2) +
Convert.ToInt32(c1, 2) +
Convert.ToInt32(d1, 2) +
Convert.ToInt32(e1, 2))
% Convert.ToInt32(f1, 2))
* Convert.ToInt32(g1, 16);
Console.WriteLine(Convert.ToString(h1, 8));

Bin32 a2 = a1;
Bin32 b2 = b1;
Bin32 c2 = c1;
Bin32 d2 = d1;
Bin32 e2 = e1;
Bin32 f2 = f1;
Hex32 g2 = g1;

// Using Bin32, Oct32, Hex32 structs - a simple one liner
Oct32 h2 = ((a2 + b2 + c2 + d2 + e2) % f2) * g2;
Console.WriteLine((String)h2);```

I also timed the code above, and both performed in roughly the same time - sometimes the first section was fractionally quicker, sometimes the second - so it's not slowing anything down at all. Working with straight `int`s is about 50x faster, but if you have data in a different base, then you have to do the conversion anyway. If you want to change it to an `int` to remove the overhead - that's what the implicit casting is for.

## Share

United Kingdom
No Biography provided

 First Prev Next
 ExtensionMethods are not full Dimps21-Jul-10 7:48 Dimps 21-Jul-10 7:48
 Can you please confirm this is 3.5 and above? OnAClearDiskYouCanSeekForever16-May-10 21:08 OnAClearDiskYouCanSeekForever 16-May-10 21:08
 Re: Can you please confirm this is 3.5 and above? DaveyM6917-May-10 9:56 DaveyM69 17-May-10 9:56
 Not for big integer sport_life21-Mar-09 18:12 sport_life 21-Mar-09 18:12
 Re: Not for big integer DaveyM6922-Mar-09 1:46 DaveyM69 22-Mar-09 1:46
 Hi Cape Town Developer7-Oct-08 2:29 Cape Town Developer 7-Oct-08 2:29
 Re: Hi DaveyM697-Oct-08 2:49 DaveyM69 7-Oct-08 2:49
 Excellent merlin9817-Oct-08 2:17 merlin981 7-Oct-08 2:17
 Re: Excellent DaveyM697-Oct-08 2:48 DaveyM69 7-Oct-08 2:48
 Last Visit: 31-Dec-99 19:00     Last Update: 5-May-15 15:58 Refresh 1