12,702,599 members (33,007 online)
alternative version

35.3K views
23 bookmarked
Posted

# Number conversion methods

, 23 Sep 2005
 Rate this:
Shows how to convert an integer to different number systems, and vice versa.

## Introduction

In the whole arena of computer programming, there exists the problem to convert a number from one number system to another. I want to solve it in a more generic way to support more than one conversion scheme in future. In the following article, I want to explain four systems that were implemented into the `xProcs.Common.Converter` namespace.

• Roman number system, i.e., X, MCDXIII
• Hexadecimal, i.e., \$FA
• Octal, i.e., o4571
• Binary, i.e., 001010111011

## Using the code

To use one concrete conversion, you simple use the `ConverterBase` class and access the converter over a static property. The following example writes out the Roman number for the year 1984:

`Console.WriteLine(ConverterBase.Roman.ToString(1984));`

The other direction works the same:

`Console.WriteLine(ConverterBase.Roman.ToInt("MCMLXXXIV"));`

## Static singleton property

If you look into the code, you'll see some things I love to do in the code. For example I define a static getter for accessing an instance of the concrete converter. It's a lazy creation, the instancing is done at the first access of the property!

```private static volatile ConverterBase binary;

static public ConverterBase Roman
{
get
{
if (roman == null)
roman = new RomanConverter();
return roman;
}
}
```

## Hexadecimal, octal and binary systems

These three conversions all use the class `PositionalNotationConverter`, because they share the same functionality and all are based on a radix of 2, 4 or 8. I only create the class converter with a different radix, that's all.

`hexadecimal = new PositionalNotationConverter(16);`

## Roman number system

This number system is a little more tricky but it is possible to implement a converter. Some use-cases for this converter are in numbering the contents in a document: I. II. III. and so on, or to show years in longer format like you see often in films. In the code, you'll see at first, the check for `MAX`. Bigger numbers than `MAX` aren't valid in the Roman-system. After this, for each digit, an index is calculated and then a simple predefined lookup-table is used to get the Roman digits.

```public override string ToString(int value)
{
if (value > MAX)
throw new ArgumentOutOfRangeException("value");

string[,] romanDigits = new string[,] {
{"M",      "C",    "X",    "I"    },
{"MM",     "CC",   "XX",   "II"   },
{"MMM",    "CCC",  "XXX",  "III"  },
{null,     "CD",   "XL",   "IV"   },
{null,     "D",    "L",    "V"    },
{null,     "DC",   "LX",   "VI"   },
{null,     "DCC",  "LXX",  "VII"  },
{null,     "DCCC", "LXXX", "VIII" },
{null,     "CM",   "XC",   "IX"   }
};

StringBuilder result = new StringBuilder(15);

for (int index = 0; index < 4; index++)
{
int power = (int) Math.Pow(10, 3 - index);
int digit = value / power;
value -= digit * power;
if (digit > 0)
result.Append(romanDigits[digit - 1,index]);
}

return result.ToString();
}```

For converting a Roman number back, the following code is used. Here the trick is to remember the old value. If it's greater than the current value it is reduced twice by the old value. Else it is only added. The `RomanDigit` function gives you back the value for a single Roman digit.

```public override int ToInt(string number)
{
int result = 0;
int oldValue = 1000;

for (int index = 0; index < number.Length; index++)
{
int newValue = RomanDigit(number[index]);
if (newValue > oldValue)
result = result + newValue - 2 * oldValue;
else
result += newValue;

oldValue = newValue;
}
return result;
}```

## Test-Case's

Here you see the test-cases I've written for the four conversion classes. That's how I check if my code works against one or more test scenarios.

```[TestFixture]
public class NumberConvertTest
{

[Test]
public void RomanNumber()
{
Assert.AreEqual("MCMLXXXIV", ConverterBase.Roman.ToString(1984));
Assert.AreEqual(1984, ConverterBase.Roman.ToInt("MCMLXXXIV"));
}

[Test]
public void HexNumber()
{
}

[Test]
public void OctNumber()
{
Assert.AreEqual("4553207", ConverterBase.Octal.ToString(1234567));
Assert.AreEqual(1234567, ConverterBase.Octal.ToInt("4553207"));
}

[Test]
public void BinaryNumber()
{
Assert.AreEqual("1010111111111110", ConverterBase.Binary.ToString(0xAFFE));
Assert.AreEqual(0xAFFE, ConverterBase.Binary.ToInt("1010111111111110"));
}
}```

## Summary

Okay, I hope that you like the code and can use it in your own projects. I want to hear from you your opinion about it. If you have your own conversion methods inherited from `ConverterBase` please send it to me, if you wish that I include it into the `xProcs.Common.Converter` namespace.

## History

xProcs is a free collection of methods that you can use in your own projects. If you have ideas or code to be included in this collection, send it to xProcs@hotmail.de.

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

## About the Author

 Web Developer Germany
No Biography provided

## You may also be interested in...

 Pro Pro

## Comments and Discussions

 First Prev Next
 you rock man! elpohito16-Oct-06 7:40 elpohito 16-Oct-06 7:40
 Last Visit: 31-Dec-99 19:00     Last Update: 24-Jan-17 2:47 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.