Delphi扩展到C#

3
如何将浮点型10字节十六进制字符串(Delphi中的Extended数据类型)转换为C#数据类型?
例如:00 00 00 00 00 00 00 80 ff 3f 在Delphi中表示1

我不太确定你的意思。您是否在C#应用程序中拥有一个包含Delphi扩展值的10字节缓冲区,并希望将其转换为C# double值?如果是这样,使用指针和一些字节传输可能可以相对容易地完成。 - Andreas Rejbrand
首先,你需要选择一个类型:double 或 decimal。这个选择取决于你的数据的范围和精度。你总会有所损失。 - H H
嗨,抱歉有些信息缺失: 我有一个十六进制字符串(通过Delphi创建),其中包含一个浮点数(10个字节->数据类型:extended)。 现在我需要将这些字节转换为C#数据类型,如double。但是double只有8个字节,因此如果我使用BitConverter.ToDouble(),结果就不正确。 - daniel
2
Delphi中的extended值是IEEE扩展浮点数。它的规范在这里:http://en.wikipedia.org/wiki/Extended_precision...... 最坏情况下,可以操作位。 - Donnie
2个回答

2

我曾遇到同样的问题,现在分享我的解决方案给需要的人:

        var extendedSize = 10;
        var buf = new byte[extendedSize];

        // Populate buffer with something like: { 0x00, 0x68, 0x66, 0x66, 0x66, 0x66, 0x66, 0xA2, 0x02, 0x40 } = 10.15
        // Read(buf, extendedSize);

        var sign = (buf[extendedSize - 1] & 0x80) == 0x80 ? -1 : 1;
        buf[extendedSize - 1] = (byte)(buf[extendedSize - 1] & 0x7F);
        var exp = BitConverter.ToUInt16(buf, extendedSize - 2);
        var integral = (buf[extendedSize - 3] & 0x80) == 0x80 ? 1 : 0;           

        // Calculate mantissa
        var mantissa = 0.0;
        var value = 1.0;
        var fractal = BitConverter.ToUInt64(buf, 0);

        while (fractal != 0)
        {
            value = value / 2;
            if ((fractal & 0x4000000000000000) == 0x4000000000000000) // Latest bit is sign, just skip it
            {
                mantissa += value;
            }
            fractal <<= 1;
        }

        return sign * (Math.Pow(2, exp - 16383)) * (integral + mantissa);    

需要改进代码,添加NaN和Inf检查,并且可能需要将"double"替换为"decimal"。


我进行了编辑并进行了更正 - 从这个问题中发现。 - J...

1

好的,这是我的解决方案:

每个字符串都包含一个因子字节在第二个位置。在我的示例中,因子是ff

现在我必须通过浮点数转换将字符串转换为十进制数并乘以因子字节以获得结果。

例如:3f ff 80 00 00(32位) -> 删除因子字节(ff) -> 3f 80 00 00 -> 转换为十进制数 -> 结果:1 -> 乘以因子 -> 1 * 1 -> 结果:1

希望这有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接