8

C++、Java 都在语言的语法中包含 [-]0xh.hhhhp+/-d 格式,其他语言如 python 和 C99 具有解析这些字符串的库支持(float.fromhex、scanf)。

我还没有找到用 C# 或使用 .NET 库来解析这种精确的十六进制编码指数格式的方法。

有没有一种很好的方法来处理这个问题,或者一个不错的替代编码?(十进制编码不准确)。

示例字符串:0x1p-8 -0xfe8p-12

谢谢

4

2 回答 2

2

不幸的是,我不知道 .NET 内置的任何方法可以与 Python 的float.fromhex()相比。所以我想你唯一能做的就是在 C# 中滚动你自己的 .fromhex() 。此任务的难度范围从“有些简单”到“非常困难”,具体取决于您希望解决方案的完成程度和优化程度。

正式地,IEEE 754规范允许在十六进制系数内使用小数(即 0xf.e8p-12),这为我们增加了一层复杂性,因为(令我沮丧的是).NET 也不支持十六进制的 Double.Parse()字符串。

如果您可以将问题限制在您提供的示例中,其中您只有整数作为系数,您可以使用以下使用字符串操作的解决方案:

public static double Parsed(string hexVal)
{
    int index = 0;
    int sign = 1;
    double exponent = 0d;

    //Check sign
    if (hexVal[index] == '-')
    {
        sign = -1;
        index++;
    }
    else if (hexVal[index] == '+')
        index++;
    //consume 0x
    if (hexVal[index] == '0')
    {
        if (hexVal[index+1] == 'x' || hexVal[index+1] == 'X')
            index += 2;
    }

    int coeff_start = index;
    int coeff_end = hexVal.Length - coeff_start;

    //Check for exponent
    int p_index = hexVal.IndexOfAny(new char[] { 'p', 'P' });
    if (p_index == 0)
        throw new FormatException("No Coefficient");
    else if (p_index > -1)
    {
        coeff_end = p_index - index;
        int exp_start = p_index + 1;
        int exp_end = hexVal.Length;
        exponent = Convert.ToDouble(hexVal.Substring(exp_start, exp_end - (exp_start)));
    }

    var coeff = (double)(Int32.Parse(hexVal.Substring(coeff_start, coeff_end), NumberStyles.AllowHexSpecifier));
    var result = sign * (coeff * Math.Pow(2, exponent));
    return result;
}

如果您正在寻找与 Python 的 fromhex() 相同的函数,您可以尝试将CPython 实现转换为 C#。我试过了,但由于我对标准不是很熟悉,并且在遵循他们正在寻找的所有溢出检查时遇到了麻烦,所以我陷入了困境。它们还允许其他内容,例如无限的前导和尾随空格,这是我的解决方案所不允许的。

我的解决方案是“有点简单”的解决方案。我猜如果你真的知道你的东西,你可以在位级别构建符号、指数和尾数,而不是把所有东西都相乘。您当然也可以一次性完成,而不是使用 .Substring() 方法作弊。

希望这至少能让你走上正轨。

于 2012-11-23T23:38:48.140 回答
2

我编写了 C# 代码,用于格式化和解析 IEEE 754r 中描述的十六进制浮点格式的数字,并受 C99、C++11 和 Java 的支持。该代码是 F# 的 BSD 许可FParsec库的一部分,包含在单个文件中: https ://bitbucket.org/fparsec/main/src/tip/FParsecCS/HexFloat.cs

支持的格式在http://www.quanttec.com/fparsec/reference/charparsers.html#members.floatToHexString有所描述

测试代码(用 F# 编写)可以在https://bitbucket.org/fparsec/main/src/tip/Test/HexFloatTests.fs找到

于 2013-02-19T20:43:16.067 回答