How to convert a "big" Hex number (in string format):
EC851A69B8ACD843164E10CFF70CF9E86DC2FEE3CF6F374B43C854E3342A2F1AC3E30C741CC41E679DF6D07CE6FA3A66083EC9B8C8BF3AF05D8BDBB0AA6CB3EF8C5BAA2A5E531BA9E28592F99E0FE4F95169A6C63F635D0197E325C5EC76219B907E4EBDCD401FB1986E4E3CA661FF73E7E2B8FD9988E753B7042B2BBCA76679
to a decimal number (in string format):
166089946137986168535368849184301740204613753693156360462575217560130904921953976324839782808018277000296027060873747803291797869684516494894741699267674246881622658654267131250470956587908385447044319923040838072975636163137212887824248575510341104029461758594855159174329892125993844566497176102668262139513
without using BigInteger
Class (as my application should support machines without .NET Framework 4)?
Here's a quick-and-dirty implementation that can work with arbitrarily-large numbers. The aim of this implementation is simplicity, not performance; thus, it should be optimized drastically if it's to be used in a production scenario.
Edit: Simplified further per Dan Byström's implementation of the inverse decimal-to-hex conversion:
static string HexToDecimal(string hex)
{
List<int> dec = new List<int> { 0 }; // decimal result
foreach (char c in hex)
{
int carry = Convert.ToInt32(c.ToString(), 16);
// initially holds decimal value of current hex digit;
// subsequently holds carry-over for multiplication
for (int i = 0; i < dec.Count; ++i)
{
int val = dec[i] * 16 + carry;
dec[i] = val % 10;
carry = val / 10;
}
while (carry > 0)
{
dec.Add(carry % 10);
carry /= 10;
}
}
var chars = dec.Select(d => (char)('0' + d));
var cArr = chars.Reverse().ToArray();
return new string(cArr);
}
I just translated Douglas' code into VBA
Function HexToDecimal(ByVal sHex As String) As String
Dim dec() As Long
ReDim dec(0 To 0) As Long
Dim lCharLoop As Long
For lCharLoop = 1 To Len(sHex)
Dim char As String * 1
char = Mid$(sHex, lCharLoop, 1)
Dim carry As Long
carry = Val("&h" & char)
Dim i As Long
For i = 0 To UBound(dec)
Dim lVal As Long
lVal = dec(i) * 16 + carry
dec(i) = lVal Mod 10
carry = lVal \ 10
Next i
While (carry > 0)
ReDim Preserve dec(0 To UBound(dec) + 1) As Long
dec(UBound(dec)) = carry Mod 10
carry = carry \ 10
Wend
Next
For lCharLoop = UBound(dec) To LBound(dec) Step -1
Dim sDecimal As String
sDecimal = sDecimal & Chr$(48 + dec(lCharLoop))
Next
HexToDecimal = sDecimal
End Function
Private Sub TestHexToDecimal()
Debug.Assert HexToDecimal("F") = "15"
Debug.Assert HexToDecimal("4") = CStr(Val("&H4"))
Debug.Assert HexToDecimal("10") = CStr(Val("&H10"))
Debug.Assert HexToDecimal("20") = CStr(Val("&H20"))
Debug.Assert HexToDecimal("30") = CStr(Val("&H30"))
Debug.Assert HexToDecimal("40") = CStr(Val("&H40"))
Debug.Assert HexToDecimal("44") = CStr(Val("&H44"))
Debug.Assert HexToDecimal("FF") = "255"
Debug.Assert HexToDecimal("FFF") = "4095"
Debug.Assert HexToDecimal("443") = CStr(Val("&H443"))
Debug.Assert HexToDecimal("443C1") = "279489"
Debug.Assert HexToDecimal("443C1CE20DFD592FB374D829B894BBE5") = "90699627342249584016268008583970733029"
Debug.Assert HexToDecimal("EC851A69B8ACD843164E10CFF70CF9E86DC2FEE3CF6F374B43C854E3342A2F1AC3E30" & _
"C741CC41E679DF6D07CE6FA3A66083EC9B8C8BF3AF05D8BDBB0AA6CB3EF8C5BAA2A5" & _
"E531BA9E28592F99E0FE4F95169A6C63F635D0197E325C5EC76219B907E4EBDCD401FB1" & _
"986E4E3CA661FF73E7E2B8FD9988E753B7042B2BBCA76679") = _
"1660899461379861685353688491843017402046137536931563604625752175601309049219" & _
"5397632483978280801827700029602706087374780329179786968451649489474169926767" & _
"4246881622658654267131250470956587908385447044319923040838072975636163137212" & _
"8878242485755103411040294617585948551591743298921259938445664971761026682621" & _
"39513"
End Sub
Also a benchmark at statman.info Hexadecimal Conversion for large numbers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With