logan_ch
logan_ch

Reputation: 33

How to create Delphi Extended 10 bytes from a number?

I know this is probably a very rare question.

I have a service written with Delphi, and a client written with C#. The Delphi service tries to read a 10-byte Extended data type from the C# client.

After some research, I found some sample code in C# to convert a 10-byte Extended to a number (Convert Delphi Extended to C#). But I couldn't find any sample to convert a number to a 10-byte Extended, so that I can send it back to the service.

I tried to write code by myself, but the calculation is very difficult for me to understand.

Can anyone help me?

Upvotes: 1

Views: 580

Answers (2)

logan_ch
logan_ch

Reputation: 33

Sorry for not make question clear, but thanks for all the comments here.

I got the code working, it looks not that perfect, but unit testing is passed.

Thanks for the link sent by @fpiette, it gave me bellow thoughts.

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

Upvotes: 0

fpiette
fpiette

Reputation: 12292

Delphi (32 bit target) natively support Extended data type. You can just copy the 10 bytes in the Extended variable. For example:

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;

The binary format for extended data type can be found here. A better description of the format is here.

Upvotes: 1

Related Questions