【问题标题】:How to convert Hex string to Decimal如何将十六进制字符串转换为十进制
【发布时间】:2014-04-28 20:21:51
【问题描述】:

当我尝试这个时,

Decimal m = Decimal.Parse(columns[1], System.Globalization.NumberStyles.AllowHexSpecifier);

我得到一个 ArgumentException 说这个,

浮点数不支持数字样式 AllowHexSpecifier 数据类型。

和列[1] = 4B414D000000011613C3 顺便说一句。

我做错了什么,我该如何解决?

【问题讨论】:

  • 列[1]是什么类型?细绳?二进制?浮点?如果是 FP,则需要强制转换或转换器,而不是解析。
  • 这是我从 csv 文件中获取的字符串

标签: c# hex converter


【解决方案1】:

Decimal 是浮点类型。尝试改用int.Parse

【讨论】:

  • 这是错误的。 C# 中的 Decimal 是 128 位定点类型,与浮点有很大不同。
  • 我错了。 Decimal 是 128 位 floatingdecimal 类型。 [没有任何借口——我一定是想到了 VB 或 COM 之类的东西。]
【解决方案2】:

Decimal 是浮点类型,例如SingleDouble,因此您无法通过标准方法解析字符串,例如

  4B414.D000000011613C3eAF // <- '.' decimal point; 'e' exponent sign  

另一方面,Decimal 接近于int128,我们没有那个超长整数。如果你的价值没那么大(小于2^63大约9.2e18)你可以尝试一下

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

如果超过 UInt64,您可以拆分您的值:

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

【讨论】:

  • 如果我这样做,我会得到 Value 对于 Int64 来说太大或太小。
  • @user3240428:在这种情况下,您可以将值拆分为两个,将它们解析为 ulong/long 并组合成十进制。查看我的编辑
【解决方案3】:

您有一个表示十六进制整数的 20 个字符的字符串,并且您想将其转换为数字格式。 20 个字符是 80 位,因此它不适合整数,但可以适合小数。十进制是 128 位浮点表示,尾数为 96 位。没有内置的转换函数可以做到这一点。

我能想到的最好的策略就是这个。

  1. 将字符串分成3部分,从右边开始,每次取8个字符。字符串将为 HI=4、MI=8 和 LO=8 个字符。
  2. 使用 Parse 和十六进制说明符将每个子字符串转换为整数。
  3. 使用 Decimal ctor 组合各个部分:Decimal(LO,MI,HI,0,0)。

详情请见http://msdn.microsoft.com/en-us/library/bb1c1a6x%28v=vs.110%29.aspx

【讨论】:

    【解决方案4】:

    这是基于 msdn 示例,其中十六进制值将转换为双精度值。并采用相同的值来验证结果。

            `double dnumber = 0;
    
            long number;
            bool result = Int64.TryParse(hexString,
                    NumberStyles.HexNumber, CultureInfo.InvariantCulture,
                    out number);
            dnumber=BitConverter.Int64BitsToDouble(number);
    
            return dnumber;`
    

    要使用它,我已经给出了示例工作程序,在控制台应用程序中使用它并检查结果。

    `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;
        }`
    

    输出将是

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-25
      • 2018-01-22
      • 2013-02-07
      • 2017-08-23
      • 2014-03-19
      • 1970-01-01
      • 2018-01-31
      相关资源
      最近更新 更多