Click here to Skip to main content
Click here to Skip to main content
Go to top

Number conversion methods

, 23 Sep 2005
Rate this:
Please Sign up or sign in to vote.
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()
    {
        Assert.AreEqual("12FEAC", ConverterBase.Hexadecimal.ToString(0x12FeAC));
        Assert.AreEqual(0x12FeAC, ConverterBase.Hexadecimal.ToInt("12FEAC"));
    }

    [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

About xProcs

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.

License

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

Share

About the Author

StefanBoether
Web Developer
Germany Germany
No Biography provided

Comments and Discussions

 
Generalyou rock man! Pinmemberelpohito16-Oct-06 6:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 24 Sep 2005
Article Copyright 2005 by StefanBoether
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid