When I try this,
Decimal m = Decimal.Parse(columns[1], System.Globalization.NumberStyles.AllowHexSpecifier);
I get an ArgumentException saying this,
The number style AllowHexSpecifier is not supported on floating point
data types.
and columns[1] = 4B414D000000011613C3 btw.
what am I doing wrong and how do I fix it ?
Decimal
is floating point type, like Single
, Double
and so you can't parse by standard means strings like
4B414.D000000011613C3eAF // <- '.' decimal point; 'e' exponent sign
On the other hand, Decimal
is close to int128
and we don;t have that super long int. If your value is not that big (less than 2^63 which about 9.2e18) you can try something
// It's OK in your case:
// 4B414D000000011613C3 (hex) = 5422700088726126870 (dec) < 9223372036854775808
// use long.Parse() or ulong.Parse(): int is too small
Decimal result = long.Parse(columns[1], System.Globalization.NumberStyles.HexNumber);
In case of exceeding the UInt64 you can split your value:
// to simplify the idea, I remove negative values support
String source = "4B414D000000011613C3";
String highPart = source.Remove(source.Length - 16);
String lowPart = source.Substring(source.Length - 16);
Decimal result =
ulong.Parse(highPart, System.Globalization.NumberStyles.HexNumber);
result = result * ulong.MaxValue + ulong.Parse(lowPart, System.Globalization.NumberStyles.HexNumber);
Decimal
is a floating point type. Try using int.Parse
instead.
You have a 20 character string representing a hexadecimal integer and you want to convert it a numeric format. 20 characters is 80 bits so it won't fit into an integer but it will fit into a Decimal. Decimal is a 128-bit floating point representation with 96 bits of mantissa. There is no built-in conversion function that can do this.
The best strategy I can think of is this.
- Break the string into 3 parts, starting from the right, taking 8 characters each time. The strings will be HI=4, MI=8 and LO=8 characters.
- Convert each sub-string into an integer using Parse and the hex specifier.
- Combine the parts using the Decimal ctor: Decimal(LO,MI,HI,0,0).
See http://msdn.microsoft.com/en-us/library/bb1c1a6x%28v=vs.110%29.aspx for details.
This is based on the msdn example where in the Hex value will be converted to doubles. And the same values has been taken to varify the results.
`double dnumber = 0;
long number;
bool result = Int64.TryParse(hexString,
NumberStyles.HexNumber, CultureInfo.InvariantCulture,
out number);
dnumber=BitConverter.Int64BitsToDouble(number);
return dnumber;`
To use this I have given sample working program, use it in a console application and check the results.
`static void Main(string[] args)
{
const string formatter = "{0,27:E16}";
Console.WriteLine(string.Format(formatter, HexStringToDouble("0")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("3FF0000000000000")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("402E000000000000")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("406FE00000000000")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("41EFFFFFFFE00000")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("3F70000000000000")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("3DF0000000000000")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("0000000000000001")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("000000000000FFFF")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("0000FFFFFFFFFFFF")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("FFFFFFFFFFFFFFFF")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("FFF0000000000000")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("7FF0000000000000")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("FFEFFFFFFFFFFFFF")));
Console.WriteLine(string.Format(formatter, HexStringToDouble("7FEFFFFFFFFFFFFF")));
Console.WriteLine(string.Format(formatter, HexStringToDouble(long.MinValue.ToString())));
Console.WriteLine(string.Format(formatter, HexStringToDouble(long.MaxValue.ToString())));
Console.ReadKey();
}
private static double HexStringToDouble(string hexString)
{
double dnumber = 0;
long number;
bool result = Int64.TryParse(hexString,
NumberStyles.HexNumber, CultureInfo.InvariantCulture,
out number);
dnumber=BitConverter.Int64BitsToDouble(number);
return dnumber;
}`
The output will be