如何从数字创建 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;
抱歉没有把问题说清楚,但感谢这里的所有评论。
我的代码可以运行了,它看起来不是很完美,但是通过了单元测试。
感谢@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;
}
我知道这可能是一个非常罕见的问题。
我有一个用 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;
抱歉没有把问题说清楚,但感谢这里的所有评论。
我的代码可以运行了,它看起来不是很完美,但是通过了单元测试。
感谢@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;
}