5,136,034 members and growing! (12,113 online)
Email Password   helpLost your password?
Languages » C# » Samples     Intermediate

Number conversion methods

By stefan.boether

Shows how to convert an integer to different number systems, and vice versa.
C#, Windows, .NET 2.0, .NETVS, VS2005, Dev

Posted: 23 Sep 2005
Updated: 23 Sep 2005
Views: 17,290
Announcements



Search    
Advanced Search
Sitemap
8 votes for this Article.
Popularity: 3.91 Rating: 4.33 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
1 vote, 12.5%
3
3 votes, 37.5%
4
4 votes, 50.0%
5

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

About the Author

stefan.boether



Occupation: Web Developer
Location: Germany Germany

Other popular C# articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 1 of 1 (Total in Forum: 1) (Refresh)FirstPrevNext
Subject  Author Date 
Generalyou rock man!memberelpohito7:40 16 Oct '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 23 Sep 2005
Editor: Smitha Vijayan
Copyright 2005 by stefan.boether
Everything else Copyright © CodeProject, 1999-2008
Web20 | Advertise on the Code Project