如何从数字创建 Delphi 扩展的 10 个字节?

How to create Delphi Extended 10 bytes from a number?

我知道这可能是一个非常罕见的问题。

我有一个用 Delphi 编写的服务和一个用 C# 编写的客户端。 Delphi 服务尝试从 C# 客户端读取 10 字节 Extended 数据类型。

经过一些研究,我在 C# 中找到了一些示例代码,可以将 10 字节的 Extended 转换为数字 (Convert Delphi Extended to C#)。但是我找不到任何示例将数字转换为 10 字节 Extended,以便我可以将其发送回服务。

我试着自己写代码,但是计算起来很难看懂。

谁能帮帮我?

Delphi(32 位目标)本机支持扩展数据类型。您可以只复制扩展变量中的 10 个字节。例如:

const
    // Binary representation of Extended number "123456789012345678"
    Bin : array [0..9] of Byte = (0, 167, 121, 24, 211,
                                  165, 77, 219, 55, 64);
procedure TForm1.Button1Click(Sender: TObject);
var
    V   : Extended;
    I    : Integer;
begin
    V := PExtended(@Bin[0])^;  // Copy Bin to V
    Memo1.Lines.Add(Format('%22f', [V]));
end;

可以找到扩展数据类型的二进制格式here。 更好的格式描述是 here.

抱歉没有把问题说清楚,但感谢这里的所有评论。

我的代码可以运行了,它看起来不是很完美,但是通过了单元测试。

感谢@fpiette 发来的link,它给了我以下的想法。

public static byte[] WriteExtendedToBuffer(double value)
    {
        var extendedBuffer = Enumerable.Repeat((byte)0x0, 10).ToArray();
        if (!double.IsNaN(value) && !double.IsInfinity(value) && (value != 0))
        {
            var doubleBuff = BitConverter.GetBytes(value);
            var sign = doubleBuff[7] & 0x80;
            doubleBuff[7] = (byte)(doubleBuff[7] & 0x7F);
            var exp = BitConverter.ToUInt16(doubleBuff, 6);
            doubleBuff[7] = 0;
            doubleBuff[6] = (byte)(doubleBuff[6] & 0x0F);
            var massive = BitConverter.ToUInt64(doubleBuff);
            exp >>= 4;
            if (exp == 0)
            {
                exp = 16383 - 1022;
                Buffer.BlockCopy(BitConverter.GetBytes(exp), 0, extendedBuffer, 8, 2);
                extendedBuffer[9] = (byte)(extendedBuffer[9] | sign);
                massive <<= 11;
                Buffer.BlockCopy(BitConverter.GetBytes(massive), 0, extendedBuffer, 0, 8);
            }
            else
            {
                exp = (ushort)(16383 + exp - 1023);
                Buffer.BlockCopy(BitConverter.GetBytes(exp), 0, extendedBuffer, 8, 2);
                extendedBuffer[9] = (byte)(extendedBuffer[9] | sign);
                massive <<= 11;
                Buffer.BlockCopy(BitConverter.GetBytes(massive), 0, extendedBuffer, 0, 8);
                extendedBuffer[7] = (byte)(extendedBuffer[7] | 0x80);
            }
        }
        return extendedBuffer;
    }