Question

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 ?

Was it helpful?

Solution 2

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);

OTHER TIPS

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.

  1. 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.
  2. Convert each sub-string into an integer using Parse and the hex specifier.
  3. 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

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top