Your problem is essentially the mask computation. You do 1 shl I
which gives a 32 bit value. You must do UInt64(1) shl I
to get a 64 bit value.
Here is your code fixed:
function MyFloatToBinString(d: double): String;
var
VP : ^UInt64;
I : Integer;
begin
VP := @d;
Result := 'F';
for I := 63 downto 0 do begin
if (VP^ and (UInt64(1) shl I)) <> 0 then
Result := Result + '1'
else
Result := Result + '0';
end;
end;
function MyBinStringToFlat(S : String) : Double;
var
V : UInt64;
I : Integer;
J : Integer;
begin
if (Length(S) <> 65) or ((S[1] <> 'F') and (S[1] <> 'f')) then
raise Exception.Create('Invalid format');
V := 0;
for I := 65 downto 2 do begin
case S[I] of
'1': V := V or (UInt64(1) shl (65 - I));
'0': { Nothing to do };
else
raise Exception.Create('Invalid format');
end;
end;
Result := PDouble(@V)^;
end;
And if you want to test:
procedure TForm1.Button1Click(Sender: TObject);
var
V1 : Double;
V2 : Double;
S : String;
begin
V1 := 3.1416;
Memo1.Lines.Add(IntToHex(PUInt64(@V1)^));
S := MyFloatToBinString(V1);
Memo1.Lines.Add(S);
V2 := MyBinStringToFlat(S);
Memo1.Lines.Add(V2.ToString);
end;
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…