Change The Positive Number Between The Systems And Vice Versa

Introduction

Numbers can be represented in different systems. .Net Framework allows you to convert numbers into 2, 8, 10, and 16.

What if you need a different system?

Solution

I suppose you have to change the positive number between the systems and vice versa.

In the beginning, I declare an alias for the type of number.

using Number = System.Numerics.BigInteger;

Change of the positive number into a different system.

Our function will be the extension method of the alias Number.

The extension method should be static and it needs to be created in a static class. Also, the first parameter should be preceded by the keyword "this”.

static string ConvertToSystem(this Number n, int System)

I use the SystemCodes table like below in this,

static char[] SystemCodes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

I check if n is positive - otherwise, I throw an exception.

I check if System is higher or equal than 2, and its length is less or equal to +1 of the SystemCodes table - otherwise, I throw an exception.

I create a StringBuilder object.

I use a do-while loop while n is not equal to 0.

Inside a loop, I calculate the remainder between n and System.

I insert a char from the SystemCodes table indexed by the remainder.

I subtract the remainder from n. I divide n by System.

In the end, I return a string from the StringBuilder object.

Change the number as text written in the system into a number.

Our function looks like this,

static Number ConverFromSystem(string nstr, int System)

I check if nstr parameter is a null or white string - otherwise, I throw an exception.

I check if System is higher or equal than 2, and its length is less or equal to +1 of the SystemCodes table - otherwise, I throw an exception.

If SystemCodesReverse is null I generate it using SystemCodes and indexed Linq select method.

I initialize n to 0.

I use a for loop from 0 to nstr parameter length -1.

Inside a loop, I get a char from nstr parameter.

I get a position in SystemCodes using SystemCodesReverse,

If I can't find a position that is higher or equal to System, I throw an exception.

I ignore the beginning position 0. I set the first non 0 value as n to the position. 

For all the next characters firstly at first I multiply n by System. Secondly, I add the position to n. I wrote it in a checked surrounding to throw an exception if there is an overflow.

In the end, I return an n.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Number = System.Numerics.BigInteger;
namespace ConvertNumberBetweenDifferentSystems {
    static class Program {
        static void Main(string[] args) {
            Number n = 254;
            Console.WriteLine(n.ConvertToSystem(16));
            Console.WriteLine(ConverFromSystem("00FE", 16));
        }
        static char[] SystemCodes = {
            '0',
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9',
            'A',
            'B',
            'C',
            'D',
            'E',
            'F'
        };
        static Dictionary < char, int > SystemCodesReverse;
        static string ConvertToSystem(this Number n, int System) {
            if (n < 0) throw new ArgumentException("The n need to be positive");
            if (System <= 1 || System > SystemCodes.Length + 1) throw new ArgumentException(string.Format("The System need to be between 2 and {0}", SystemCodes.Length + 1));
            var sb = new StringBuilder();
            do {
                var remainder = (int) n % System;
                sb.Insert(0, SystemCodes[remainder]);
                n = (Number)(n - remainder);
                n = (Number)(n / System);
            } while (n != 0);
            return sb.ToString();
        }
        static Number ConverFromSystem(string nstr, int System) {
            if (string.IsNullOrWhiteSpace(nstr)) throw new ArgumentException("The nstr parameter is empty");
            if (System <= 1 || System > SystemCodes.Length + 1) throw new ArgumentException(string.Format("The System need to be between 2 and {0}", SystemCodes.Length + 1));
            if (SystemCodesReverse == null) SystemCodesReverse = SystemCodes.Select((c, i) => new {
                i,
                c
            }).ToDictionary(o => o.c, o => o.i);
            Number n = 0;
            bool start = false;
            for (int i = 0; i < nstr.Length; i++) {
                var ch = nstr[i];
                int pos;
                if (SystemCodesReverse.ContainsKey(ch)) {
                    pos = SystemCodesReverse[ch];
                    if (pos >= System) throw new ArgumentException(string.Format("Invalid char {0} is not valid in system {1}", ch, System));
                } else throw new ArgumentException(string.Format("Invalid char {0} in number", ch));
                if (!start) {
                    if (pos != 0) {
                        n = (Number) pos;
                        start = true;
                    }
                } else checked {
                    n = (Number)(n * System);
                    n = (Number)(n + pos);
                }
            }
            return n;
        }
    }
}

Summary

We can see that implementing the change in the positive number between the systems and vice versa is not that complicated but just the opposite. We could use these functions for encryption and decryption data.