Skip to content

Commit 630b066

Browse files
committed
support fractions in base converter
1 parent 51d5265 commit 630b066

File tree

2 files changed

+104
-9
lines changed

2 files changed

+104
-9
lines changed

Advanced.Algorithms.Tests/BitAlgorithms/BaseConversion_Tests.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,40 @@ public class BaseConversion_Tests
1414
[TestMethod]
1515
public void BaseConversion_Smoke_Test()
1616
{
17+
//decimal to binary
18+
Assert.AreEqual("11",
19+
BaseConversion.Convert("1011", "01",
20+
"0123456789"));
21+
22+
//binary to decimal
23+
Assert.AreEqual("11.5",
24+
BaseConversion.Convert("1011.10", "01",
25+
"0123456789"));
26+
27+
//decimal to base3
1728
Assert.AreEqual("Foo",
1829
BaseConversion.Convert("9", "0123456789",
1930
"oF8"));
2031

32+
//base3 to decimal
2133
Assert.AreEqual("9",
2234
BaseConversion.Convert("Foo", "oF8",
2335
"0123456789"));
2436

37+
//hex to binary
2538
Assert.AreEqual("10011",
2639
BaseConversion.Convert("13", "0123456789abcdef",
2740
"01"));
2841

29-
Assert.AreEqual("JAM!",
30-
BaseConversion.Convert("CODE", "O!CDE?",
31-
"A?JM!."));
42+
//decimal to hex
43+
Assert.AreEqual("5.0e631f8a0902de00d1b71758e219652b",
44+
BaseConversion.Convert("5.05620", "0123456789",
45+
"0123456789abcdef"));
46+
47+
//hex to decimal with precision 5
48+
Assert.AreEqual("5.05619",
49+
BaseConversion.Convert("5.0e631f8a0902de00d1b71758e219652b", "0123456789abcdef",
50+
"0123456789", 5));
3251

3352
}
3453
}

Advanced.Algorithms/BitAlgorithms/BaseConversion.cs

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,39 @@ public class BaseConversion
1515
/// <param name="srcBaseChars">Should be in correct order => eg. 0123456789 for decimal</param>
1616
/// <param name="dstBaseChars">>Should be in correct order => eg. 01 for binary</param>
1717
/// <returns></returns>
18-
public static string Convert(string srcNumber,
18+
public static string Convert(string srcNumber,
1919
string srcBaseChars,
20-
string dstBaseChars)
20+
string dstBaseChars, int precision = 32)
2121
{
22+
srcNumber = srcNumber.Trim();
23+
if (srcNumber.Contains("."))
24+
{
25+
var tmp = srcNumber.Split('.');
26+
var whole = tmp[0].TrimEnd();
27+
var fraction = tmp[1].TrimStart();
28+
29+
return ConvertWhole(whole, srcBaseChars, dstBaseChars) +
30+
"." + ConvertFraction(fraction, srcBaseChars, dstBaseChars, precision);
31+
}
32+
33+
return ConvertWhole(srcNumber, srcBaseChars, dstBaseChars);
34+
}
35+
/// <summary>
36+
/// Converts base of given number
37+
/// </summary>
38+
/// <param name="srcNumber">input number in source base system</param>
39+
/// <param name="srcBaseChars">Should be in correct order => eg. 0123456789 for decimal</param>
40+
/// <param name="dstBaseChars">>Should be in correct order => eg. 01 for binary</param>
41+
/// <returns></returns>
42+
private static string ConvertWhole(string srcNumber,
43+
string srcBaseChars,
44+
string dstBaseChars)
45+
{
46+
if (string.IsNullOrEmpty(srcNumber))
47+
{
48+
return string.Empty;
49+
}
50+
2251
var srcBase = srcBaseChars.Length;
2352
var dstBase = dstBaseChars.Length;
2453

@@ -27,7 +56,7 @@ public static string Convert(string srcNumber,
2756
throw new Exception("Invalid source base length.");
2857
}
2958

30-
if (dstBase <=1)
59+
if (dstBase <= 1)
3160
{
3261
throw new Exception("Invalid destination base length.");
3362
}
@@ -36,16 +65,17 @@ public static string Convert(string srcNumber,
3665
var j = 0;
3766
//convert to base 10
3867
//move from least to most significant numbers
39-
for(int i=srcNumber.Length-1;i >= 0;i--)
68+
for (int i = srcNumber.Length - 1; i >= 0; i--)
4069
{
4170
//eg. 1 * 2^0
42-
base10Result += (long)((srcBaseChars.IndexOf(srcNumber[i])) * Math.Pow(srcBase, j));
71+
base10Result += (srcBaseChars.IndexOf(srcNumber[i]))
72+
* (long)(Math.Pow(srcBase, j));
4373
j++;
4474
}
4575

4676
var result = new StringBuilder();
4777
//now convert to target base
48-
while(base10Result!=0)
78+
while (base10Result != 0)
4979
{
5080
var rem = (int)base10Result % dstBase;
5181
result.Insert(0, dstBaseChars[rem]);
@@ -55,5 +85,51 @@ public static string Convert(string srcNumber,
5585
return result.ToString();
5686

5787
}
88+
89+
private static string ConvertFraction(string srcNumber,
90+
string srcBaseChars,
91+
string dstBaseChars, int maxPrecision)
92+
{
93+
if (string.IsNullOrEmpty(srcNumber))
94+
{
95+
return string.Empty;
96+
}
97+
98+
var srcBase = srcBaseChars.Length;
99+
var dstBase = dstBaseChars.Length;
100+
101+
if (srcBase <= 1)
102+
{
103+
throw new Exception("Invalid source base length.");
104+
}
105+
106+
if (dstBase <= 1)
107+
{
108+
throw new Exception("Invalid destination base length.");
109+
}
110+
111+
decimal base10Result = 0;
112+
//convert to base 10
113+
//move from most significant numbers to least
114+
for (int i = 0; i < srcNumber.Length; i++)
115+
{
116+
//eg. 1 * 1/(2^1)
117+
base10Result += (srcBaseChars.IndexOf(srcNumber[i]))
118+
* (decimal)(1 / Math.Pow(srcBase, i + 1));
119+
}
120+
121+
var result = new StringBuilder();
122+
//now convert to target base
123+
while (base10Result != 0 && maxPrecision > 0)
124+
{
125+
base10Result = base10Result * dstBase;
126+
result.Append(dstBaseChars[(int)Math.Floor(base10Result)]);
127+
base10Result -= Math.Floor(base10Result);
128+
maxPrecision--;
129+
}
130+
131+
return result.ToString();
132+
133+
}
58134
}
59135
}

0 commit comments

Comments
 (0)